Supplemental file s2

In this Rmarkdown we provide the following workflow:

  • Objective 0. To investigate general literature characteristics such as time trends

  • Objective 1. To investigate the types of pesticides and pesticide classes, both in terms of the chemical structure and target organism, that have been used in studies examining the effects of pesticide exposure on post-larval zebrafish behaviour

  • Objective 2. To characterise the study set ups (e.g., characteristics of pesticides such as concentrations and duration of exposure and, characteristics of zebrafish such as life stage of exposure and sex) have been employed to assess the effects of pesticide exposure on the behaviour of post-larval zebrafish.

  • Objective 3. To identify the extent the specific behaviours have been investigated in pesticide exposure studies that use post-larval zebrafish as a model.

  • Objective 4. To assess the research contributions of different countries and continents and describe the level of collaboration between authors amongst different countries.

Load packages and Data

Load packages

pacman::p_load(tidyverse,
               here,
               stringr,
               knitr,
               formatR,
               forcats,
               ggplot2,
               hrbrthemes, 
               patchwork,
               plotly, 
               bibliometrix,
               igraph, 
               tidyr,
               circlize,
               cowplot, 
               mapproj)

Load data

All extracted data is stored in five separate .csv files representing different aspects of the data (extracted via structured predefined Google Forms - one per table)

Bibliographic data records are exported from Scopus (including cited references field) in .bib format and locally saved as scopus.bib

# Load data set containing background information on each study
bib <- read_csv(here("data", "zf_sm_bibliometrics.csv"), skip = 0) # 83 rows 9 columns 

# Load data set containing information on the design of each study 
sd <- read_csv(here("data","zf_sm_study_details.csv"), skip = 0) #  83 rows 10 columns 

# Load data set containing details of each pesticide used in each exposure studies
pd <- read_csv(here("data", "zf_sm_pesticide_details.csv"), skip = 0) # 83 rows 9 columns 

# Load data set containing details of dosage and duration of pesticide exposure 
pdo <-read_csv(here("data","zf_sm_pesticide_dosage.csv"), skip = 0) # 108 rows 12 columns 

# Load data set containing details of behaviorus measured in response to pesticide exposure 
bd <- read_csv(here("data", "zf_sm_behaviour_details.csv"), skip = 0) # 83 rows 13 columns 

# Load bibliometric information extracted from scopus 
bib_sco <- convert2df(here("data","scopus.bib"), dbsource = "scopus", format = "bibtex") # 79 rows 38 columns 
## 
## Converting your scopus collection into a bibliographic dataframe
## 
## Done!
## 
## 
## Generating affiliation field tag AU_UN from C1:  Done!

Objective 0

To investigate general literature characteristics such as time trends

Figure 2

Current time trends of articles investigating the impacts of pesticide exposure on zebrafish behaviour

# Count the number of articles by year
fig1 <- bib %>%
  count(publication_year) %>%
  
  # Create a bar chart with publication year on x-axis and count on y-axis
  ggplot(aes(x = publication_year, y = n)) +
  
  # Customize the appearance of the bars
  geom_bar(stat = "identity", fill = "#5F85AE", color = "white", alpha = 0.8, position = position_dodge(0.9)) +
  
  # Add labels to the bars
  geom_text(aes(label = n), position = position_stack(vjust = 0.5), fontface = "bold", color = "white", size = 5, hjust = 0.5) +
  
  # Customize the appearance of the plot
  theme_minimal() +
  labs(x = "Year", y = "Article Count") +
  theme(legend.position = "none",
        axis.title.x = element_text(size = 15, face = "bold"),
        axis.title.y = element_text(size = 15, face = "bold"),
        axis.text.x = element_text(angle = 45, hjust = 1, size = 15),
        axis.text.y = element_text(size = 15),
        panel.grid.major.y = element_line(color = "gray"),
        panel.grid.minor.y = element_blank(),
        plot.title = element_text(size = 16, face = "bold"))
 

fig1

 ggsave(here("figures", "fig2_time_trends.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "fig2_time_trends.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Objective 1

To investigate the types of pesticides and pesticide classes, both in terms of chemical and target, that have been used in experiments examining the effects of pesticide exposure on zebrafish behaviour.

Figure 3A

Percentages and counts of included papers on the effects of pesticides on zebrafish behaviour (raw count is provided within each bar) according to individual pesticides (“other” is a total for all pesticides with a publication count less than or equal to two)

# Separate rows with multiple pesticides, count their occurrence, and combined all pesticide that occured once as "other"
total_pesticide_count <- pd %>%
  separate_rows(pesticide_investigated, sep = ", ") %>%
  count(pesticide_investigated) %>%
  mutate(pesticide_investigated = ifelse(n<= 2, "other", as.character(pesticide_investigated))) %>%
  # "other" includes triamefon, pyriproxyfen, imidacloprid, fipronil, dieldrin, diazinon, DDT, cypermethrin, tribotyltin, terbutylazine, sodium fluride, pyrimethonil, pyraclostrobin, propiconazole, prochloraz, parathion, paclobutazol, monocotophos, methylbenzoate, methylbenzoate, methomyl, mecroprop, linuron, endosulfan, diuron, difenoconazole, dicamba,   cyprodinil, chlorothalonil, carbofuran, carbaryl, broflanilide and boscalid. 
  
  group_by(pesticide_investigated) %>%
  summarise(n = sum(n))

  # Calculate pesticide count as a percentage 
  pesticide_pct <- total_pesticide_count %>%
  mutate(proportion = n/sum(total_pesticide_count$n),
         percentage = proportion*100)
  
# Create a bar chart with the count of pesticides on the x-axis and pesticides on the y-axis
fig3a <-  ggplot(pesticide_pct, aes(x = reorder(pesticide_investigated, n), y = percentage)) +
  
  # Customize the appearance of the bars
  geom_bar(stat = "identity", fill = "#5F85AE", color = "white", alpha = 0.8, position = position_dodge(0.9)) +
  
  # Add labels to the bars for absolute count 
  geom_text(aes(label = n), position = position_stack(vjust = 0.5), color = "white", fontface = "bold", size = 7) +
  

  # Add labels to the bars for percentage 
 geom_text(data = pesticide_pct, aes(label = paste0(round(percentage,1), "%")), 
            position = position_dodge(width = 0.9), hjust = -0.1, size = 7, color = "black", fontface = "bold") +
  
  # Customize the appearance of the plot
  labs(x = "Pesticide", y = "Percentage") +
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
        axis.line.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.title.x = element_text(size = 25),
        axis.title.y = element_text(size = 25),
        axis.text.x = element_text(size = 20),
        axis.text.y = element_text(size = 25),
        axis.title = element_text(size = 25),
        plot.title = element_blank()) +
        coord_flip() +
        ylim(0,50) +
        labs(tag = "A")


fig3a

  ggsave(here("figures", "fig3a_pesticide_count.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
  ggsave(here("figures", "fig3a_pesticide_count.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure 3B

Percentages and counts of included papers on the effects of pesticides on zebrafish behaviour (raw count is provided within each bar) according to target classes of pesticides

# Separate rows with multiple pesticides and count their occurrence
total_target_class_count <- pd %>%
  separate_rows(pesticide_target_class, sep = ",\\s*") %>%  
  count(pesticide_target_class) 

# Calculate target class count as a percentage 
  target_class_pct <- total_target_class_count %>%
  mutate(proportion = n/sum(total_target_class_count$n),
         percentage = proportion*100)
  
# Create a bar chart with the count of target classes  on the x-axis and pesticides target class  on the y-axis
fig3b <- ggplot(target_class_pct, aes(reorder(pesticide_target_class, n), y = percentage)) +
  
  # Customize the appearance of the bars
  geom_bar(stat = "identity", fill = "#5F85AE", color = "white", alpha = 0.8, position = position_dodge(0.9)) + 
  
  # Add labels to the bars for absolute count
  geom_text(aes(label = n), position = position_stack(vjust = 0.5), color = "white", fontface = "bold", size = 7) +
  
  # Add labels to the bars for percentage 
 geom_text(data = target_class_pct, aes(label = paste0(round(percentage, 1), "%")), 
            position = position_dodge(width = 0.9), hjust = -0.2, size = 7, color = "black", fontface = "bold") +
    
  # Customize the appearance of the plot
  labs(x = "Pesticide Target Class", y = "Percentage") +
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
    axis.line.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_text(size = 15),
    axis.text.y = element_text(size = 20),
    axis.title.x = element_text(size = 20),
    axis.title.y = element_text(size = 20),
    plot.title = element_blank()) +
    coord_flip() +
    ylim(0, 80) +
    labs(tag = "B")


fig3b

 ggsave(here("figures", "fig3b_pesticide_target_count.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "fig3b_pesticide_target_count.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure 3C

Percentages and counts of included papers on the effects of pesticides on zebrafish behaviour (raw count is provided within each bar) according to chemical classes of pesticides (“other” is all pesticide chemical classes with publication count less than or equal to two)

# Separate rows with multiple pesticides and count their occurrence, then filter for cases with more than one occurrence
total_chemical_class_count <- pd %>%
  separate_rows(pesticide_chemical_class, sep = ",\\s*") %>%  
  count(pesticide_chemical_class) %>%
   mutate(pesticide_chemical_class = ifelse(n<= 2, "other", as.character(pesticide_chemical_class))) %>%
  # "other" includes pyridine, phenylurea, neonicitinoid, monochlorobenzens, aminopyrimidine, viologen, trialkyltins, strobilurin, organohalogen, imidazole, inorganic ionic compound, auxin, 
  group_by(pesticide_chemical_class) %>%
  summarise(n = sum(n))

# Calculate target class count as a percentage 
  chemical_class_pct <- total_chemical_class_count %>%
  mutate(proportion = n/sum(total_chemical_class_count$n),
         percentage = proportion*100)
  
  # Create a bar chart with the count of chemical classes on the x-axis and pesticides chemical class on the y-axis
 fig3c <-  ggplot(chemical_class_pct, aes(x = reorder(pesticide_chemical_class,n), y = percentage)) +
  
  # Customize the appearance of the bars
  geom_bar(stat = "identity", fill = "#5F85AE", color = "white", alpha = 0.8, position = position_dodge(0.9)) +
  
  # Add labels to the bars
  geom_text(aes(label = n), position = position_stack(vjust = 0.5), color = "white", fontface = "bold", size = 7) +
  
   
  # Add labels to the bars for percentage 
 geom_text(data = chemical_class_pct, aes(label = paste0(round(percentage,1), "%")), 
            position = position_dodge(width = 0.9), hjust = -0.2, size = 7, color = "black", fontface = "bold") +
   
  # Customize the appearance of the plot
  labs(x = "Pesticide Chemical Class", y = "Percentage") +
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
    axis.line.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_text(size = 15),
    axis.text.y = element_text(size = 20),
    axis.title.x = element_text(size = 20),
    axis.title.y = element_text(size = 20),
    plot.title = element_blank()) +
    coord_flip() +
    ylim(0, 40) +
    labs(tag = "C")
    

fig3c

  ggsave(here("figures", "fig3c_pesticide_chemical_count.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
  ggsave(here("figures", "fig3c_pesticide_chemical_count.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure 3

Bar charts showing the percentages and counts of included studies on the effects of pesticides on zebrafish behaviour (raw count is provided within each bar). Counts are according to a) individual pesticides (“other” is a total for all pesticides with a publication count less than or equal to two), b) target classes of pesticides, and c) chemical classes of pesticides (“other” is all pesticide chemical classes with publication count less than or equal to two)

# Combine three plots into a single plot using a grid layout
fig3 <- ((fig3a) | (fig3b / fig3c))

fig3

 ggsave(here("figures", "fig3_pesticide_count_combined.pdf"), width = 25, height = 12, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "fig3_pesticide_count_combined.jpg"), width = 25, height = 12, units = "cm", scale = 2, dpi = 800)

Objective 2

To investigate pesticide exposure study designs such as concentration and duration of exposure, life stages of zebrafish used in each study and the sample sizes used.

making dosages consistent for dosage comparisons

pdo <- pdo %>%
  # Remove rows with NA values
  filter(!is.na(dosage_lowest)) %>%
  # Convert dosage_lowest to numeric and dosage_lowest_unit to character
  mutate(dosage_lowest = as.numeric(dosage_lowest),
         dosage_lowest_unit = as.character(dosage_lowest_unit),
         
         # Standardize dosage_unit_consistent based on dosage_lowest_unit
         dosage_unit_consistent = case_when(
           dosage_lowest_unit == "mg/L" ~ "ug/L",
           dosage_lowest_unit == "ng/L" ~ "ug/L",
           dosage_lowest_unit == "g/L" ~ "ug/L",
           dosage_lowest_unit == "ppb" ~ "ug/L",
           dosage_lowest_unit == "ppm" ~ "ug/L",
           TRUE ~ dosage_lowest_unit),
         
         # Convert dosage_lowest to ug/L based on dosage_lowest_unit
         dosage_lowest_convert_ugL = case_when(
           dosage_lowest_unit == "mg/L" ~ dosage_lowest * 1000,
           dosage_lowest_unit == "ng/L" ~ dosage_lowest / 1000,
           dosage_lowest_unit == "g/L" ~ dosage_lowest/1000000,
           dosage_lowest_unit == "ppb" ~ dosage_lowest * 1000,
           dosage_lowest_unit == "ppm" ~ dosage_lowest/1000,
           TRUE ~ dosage_lowest),
         
         # Convert dosage_highest to numeric and dosage_highest_unit to character
         dosage_highest = as.numeric(dosage_highest),
         
         # Convert dosage_highest to ug/L based on dosage_highest_unit
         dosage_highest_convert_ugL = case_when(
           dosage_highest_unit == "mg/L" ~ dosage_highest * 1000,
           dosage_highest_unit == "ng/L" ~ dosage_highest / 1000,
           dosage_highest_unit == "g/L" ~ dosage_highest/1000000,
           dosage_highest_unit == "ppb" ~ dosage_highest * 1000,
           dosage_highest_unit == "ppm" ~ dosage_highest/1000,
           TRUE ~ dosage_highest))

Figure 4A

Box and violin plot illustrating the distribution of pesticide dosages used in pesticide exposure studies on zebrafish behaviour

# Pivot the dataset to a longer format, separating out the dosage type (lowest or highest) and value into separate columns
pdo_waterbourne <- pdo %>%
  pivot_longer(cols = c(dosage_lowest, dosage_highest), 
               names_to = "dosage_type",
               values_to = "dosage_value") %>% 
  
  # Filter for waterborne routes with consistent dosage units and a dosage number greater than 1
  filter(route == "waterbourne", dosage_unit_consistent == "ug/L",
         dosage_number > 1) %>%  
  
  # Rename the dosage type column for better labeling in the plot
  mutate(dosage_type = if_else(dosage_type == "dosage_lowest", "Lowest Dosage Exposed", "Highest Dosage Exposed")) 

# Create the plot with dosage type (i.e., lowest or highest dose) on the x-axis and dosage value on the y-axis
fig4a <- ggplot(pdo_waterbourne, aes(x = dosage_type, y = log(dosage_value))) +
  
  # Add a violin plot 
  geom_violin(fill = "#5F85AE", alpha =0.2, color = NA, trim = FALSE) +

  # Add a boxplot 
  geom_boxplot(width = 0.05, fill = "white", color = "#5F85AE", outlier.shape = NA) +

  # Add jittered points .
  geom_jitter(width = 0.1, height = 0.05, color = "#5F85AE", alpha = 0.8) +

  
  # Add axis and plot labels
  labs(title = "Waterborne Exposures by Dosage in ug/L", x = "Waterborne Exposure", y = "log(Dosage) [ug/L]") +
  
  # Customize plot theme
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
    axis.line.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_text(size = 15),
    axis.text.y = element_text(size = 20),
    axis.title.x = element_text(size = 20),
    axis.title.y = element_text(size = 20),
    plot.title = element_blank()) +
    labs(tag = "A")

fig4a

 ggsave(here("figures", "fig4a_pesticide_dosage.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "fig4a_pesticide_dosage.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s3

Box and violin plot illustrating the distribution of deltamethrin dosages used in pesticide exposure studies on zebrafish behaviour

# Pivot the data set to a longer format, separating out the dosage type (lowest or highest) and value into separate columns
pdo_waterbourne_deltamethrin <- pdo %>%
  pivot_longer(cols = c(dosage_lowest, dosage_highest), 
               names_to = "dosage_type",
               values_to = "dosage_value") %>% 
  
  # Filter for waterborne routes with consistent dosage units and only deltamethrin pesticide investigated
  filter(route == "waterbourne", dosage_unit_consistent == "ug/L", pesticide_investigated == "deltamethrin") %>% 

  # Rename the dosage type column for better labeling in the plot
  mutate(dosage_type = if_else(dosage_type == "dosage_lowest", "Lowest Dosage Exposed", "Highest Dosage Exposed"))

# Create the plot with dosage type (i.e., lowest or highest dose) on the x-axis and dosage value on the y-axis
figs3 <- ggplot(pdo_waterbourne_deltamethrin, aes(x = dosage_type, y = log(dosage_value))) +
  
  # Add a violin plot 
  geom_violin(fill = "#5F85AE", alpha = 0.2, color = NA, trim = FALSE) +
  
  # Add a boxplot 
  geom_boxplot(width = 0.05, fill = "white", color = "#5F85AE", outlier.shape = NA) +
  
  # Add jittered points
  geom_jitter(width = 0.1, height = 0.05, color = "#5F85AE", alpha = 0.5) +
  
  # Add axis and plot labels
  labs(title = "Waterborne Exposures of Deltamethrin by Dosage in ug/L", x = "Waterbourne exposure", y = "log(Dosage) [ug/L]") +
  
  # Customize plot theme
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
        axis.line.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.text.x = element_text(size = 15),
        axis.text.y = element_text(size = 20, hjust = 1),
        axis.title.x = element_text(size = 20),
        axis.title.y = element_text(size = 20),
        plot.title = element_blank())

figs3

  ggsave(here("figures", "figs3_pesticide_dosage_deltamethrin.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
  ggsave(here("figures", "figs3_pesticide_dosage_deltamethrin.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s4

Box and violin plot illustrating the distribution of rotenone dosages used in pesticide exposure studies on zebrafish behaviour

# Pivot the data set to a longer format, separating out the dosage type (lowest or highest) and value into separate columns
pdo_waterbourne_rotenone <- pdo %>%
  pivot_longer(cols = c(dosage_lowest, dosage_highest), 
               names_to = "dosage_type",
               values_to = "dosage_value") %>% 
  
  # Filter for waterborne routes with consistent dosage units and only rotenone pesticide investigated
  filter(route == "waterbourne", dosage_unit_consistent == "ug/L", pesticide_investigated == "rotenone") %>% 
  
  # Rename the dosage type column for better labeling in the plot
  mutate(dosage_type = if_else(dosage_type == "dosage_lowest", "Lowest Dosage Exposed", "Highest Dosage Exposed"))

# Create the plot with dosage type (i.e., lowest or highest dose) on the x-axis and dosage value on the y-axis
figs4 <- ggplot(pdo_waterbourne_rotenone, aes(x = dosage_type, y = log(dosage_value))) +
  
  # Add a violin plot 
  geom_violin(fill = "#5F85AE", alpha = 0.3, trim = FALSE, color = NA) +
  
  # Add a boxplot 
  geom_boxplot(width = 0.05, fill = "white", color = "#5F85AE", outlier.shape = NA) +
  
  # Add jittered points
  geom_jitter(width = 0.1, height = 0.05, color = "#5F85AE", alpha = 0.5) +
  
  # Add axis and plot labels
  labs(title = "Waterborne Exposures of Rotenone by Dosage in ug/L", x = "Waterbourne exposure", y = "log(Dosage) [ug/L]") +
  
  # Customize plot theme
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
        axis.line.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.text.x = element_text(size = 15),
        axis.text.y = element_text(size = 20, hjust = 1),
        axis.title.x = element_text(size = 20),
        axis.title.y = element_text(size = 20),
        plot.title = element_blank())
figs4

   ggsave(here("figures", "figs4_pesticide_dosage_rotenone.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
   ggsave(here("figures", "figs4_pesticide_dosage_rotenone.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s5

Box and violin plot illustrating the distribution of atrazine dosages used in pesticide exposure studies on zebrafish behaviour

# Pivot the data set to a longer format, separating out the dosage type (lowest or highest) and value into separate columns
pdo_waterbourne_atrazine <- pdo %>%
  pivot_longer(cols = c(dosage_lowest, dosage_highest), 
               names_to = "dosage_type",
               values_to = "dosage_value") %>% 

  # Filter for waterborne routes with consistent dosage units and only atrazine pesticide investigated
  filter(route == "waterbourne", dosage_unit_consistent == "ug/L", pesticide_investigated == "atrazine") %>%  

  # Rename the dosage type column for better labeling in the plot
  mutate(dosage_type = if_else(dosage_type == "dosage_lowest", "Lowest Dosage Exposed", "Highest Dosage Exposed"))

# Create the plot with dosage type (i.e., lowest or highest dose) on the x-axis and dosage value on the y-axis
figs5 <- ggplot(pdo_waterbourne_atrazine, aes(x = dosage_type, y = log(dosage_value))) +

  # Add a violin plot 
  geom_violin(fill = "#5F85AE", alpha = 0.3, trim = FALSE, color = "NA") +

  # Add a boxplot 
  geom_boxplot(width = 0.05, fill = "white", color = "#5F85AE", outlier.shape = NA) +

  # Add jittered points
  geom_jitter(width = 0.1, height = 0.05, color = "#5F85AE", alpha = 0.5) +

  # Add axis and plot labels
  labs(title = "Waterborne Exposures of Atrazine by Dosage in ug/L", x = "Waterborne exposure", y = "log(Dosage) [ug/L]")  +

  # Customize plot theme
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
    axis.line.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_text(size = 15),
    axis.text.y = element_text(size = 20, hjust = 1),
    axis.title.x = element_text(size = 20),
    axis.title.y = element_text(size = 20),
    plot.title = element_blank())


figs5

 ggsave(here("figures", "figs5_pesticide_dosage_atrazine.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "figs5_pesticide_dosage_atrazine.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s6

Box and violin plot illustrating the distribution of glyphosate dosages used in pesticide exposure studies on zebrafish behaviour

# Pivot the data set to a longer format, separating out the dosage type (lowest or highest) and value into separate columns
pdo_waterbourne_glyphosate <- pdo %>%
  pivot_longer(cols = c(dosage_lowest, dosage_highest), 
               names_to = "dosage_type",
               values_to = "dosage_value") %>% 
  
  # Filter for waterborne routes with consistent dosage units and only glyphosate pesticide investigated
  filter(route == "waterbourne", dosage_unit_consistent == "ug/L", pesticide_investigated == "glyphosate") %>%  
  
  # Rename the dosage type column for better labeling in the plot
  mutate(dosage_type = if_else(dosage_type == "dosage_lowest", "Lowest Dosage Exposed", "Highest Dosage Exposed"))


# Create the plot with dosage type (i.e., lowest or highest dose) on the x-axis and dosage value on the y-axis
figs6 <- ggplot(pdo_waterbourne_glyphosate, aes(x = dosage_type, y = log(dosage_value))) +
  
  # Add a violin plot
 geom_violin(fill = "#5F85AE", alpha = 0.3, trim = FALSE, color = NA) +
  
  # Add a boxplot
  geom_boxplot(width = 0.05, fill = "white", color = "#5F85AE", outlier.shape = NA) +
  
  # Add jittered points
  geom_jitter(width = 0.1, height = 0.05, color = "#5F85AE", alpha = 0.5) +
  
  # Add axis and plot labels
  labs(title = "Waterborne Exposures of Glyphosate by Dosage in ug/L", x = "Waterbourne exposure", y = "log(Dosage) [ug/L]")  +
  
  # Customize plot theme
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
    axis.line.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_text(size = 15),
    axis.text.y = element_text(size = 20, hjust = 1),
    axis.title.x = element_text(size = 20),
    axis.title.y = element_text(size = 20),
    plot.title = element_blank())

figs6

 ggsave(here("figures", "figs6_pesticide_dosage_glyphosate.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "figs6_pesticide_dosage_glyphosate.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s7

Box and violin plot illustrating the distribution of chlorpyrifos dosages used in pesticide exposure studies on zebrafish behaviour

# Pivot the data set to a longer format, separating out the dosage type (lowest or highest) and value into separate columns
pdo_waterbourne_chloropyrifo <- pdo %>%
  pivot_longer(cols = c(dosage_lowest, dosage_highest), 
               names_to = "dosage_type",
               values_to = "dosage_value") %>% 
  
  # Filter for waterborne routes with consistent dosage units and only glyphosate pesticide investigated
  filter(route == "waterbourne", dosage_unit_consistent == "ug/L", pesticide_investigated == "chloropyrifo") %>%  
  
  # Rename the dosage type column for better labeling in the plot
  mutate(dosage_type = if_else(dosage_type == "dosage_lowest", "Lowest Dosage Exposed", "Highest Dosage Exposed"))

# Create the plot with dosage type (i.e., lowest or highest dose) on the x-axis and dosage value on the y-axis
figs7 <- ggplot(pdo_waterbourne_chloropyrifo, aes(x = dosage_type, y = log(dosage_value))) +
  
  # Add a violin plot
  geom_violin(fill = "#5F85AE", alpha = 0.3, trim = FALSE, color = NA) +
  
  # Add a boxplot
  geom_boxplot(width = 0.05, fill = "white", color = "#5F85AE", outlier.shape = NA) +
  
  # Add jittered points
  geom_jitter(width = 0.1, height = 0.05, color = "#5F85AE", alpha = 0.5) +

  # Add axis and plot labels
  labs(title = "Waterborne Exposures of Chloropyrifos by Dosage in ug/L", x = "Waterbourne exposure", y = "log(Dosage) [ug/L]")  +
  
  # Customize plot theme
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
    axis.line.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_text(size = 15),
    axis.text.y = element_text(size = 20, hjust = 1),
    axis.title.x = element_text(size = 20),
    axis.title.y = element_text(size = 20),
    plot.title = element_blank())

figs7

  ggsave(here("figures", "figs7_pesticide_dosage_chloropyrifo.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
  ggsave(here("figures", "figs7_pesticide_dosage_chloropyrifo.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure 4B

Plot showing the distribuion of durations of pesticide exposure used in each study (filtered for waterborne exposure)

pdo_duration <- pdo %>% 
  filter(!is.na(duration), duration != "not reported") %>%
  # Convert duration to numeric and duration_unit to character 
  mutate(duration = as.numeric(duration),
         duration_unit = as.character(duration_unit),
         
  # Standardize duration_unit_consistent based on dosage_unit 
  duration_unit_consistent = case_when(
          duration_unit == "minutes" ~ "hours",
          duration_unit == "days" ~ "hours",
          duration_unit == "weeks" ~ "hours",
           TRUE ~ duration_unit),
  
  # Convert duration to hours based on duration_unit
  
  duration_convert = case_when(
    duration_unit == "minutes" ~ duration* 60,
    duration_unit == "days" ~ duration/24, 
    duration_unit == "weeks" ~ duration/168,
    TRUE ~ duration)) %>% 
  filter(route == "waterbourne")
  

fig4b <- ggplot(pdo_duration, aes(x = route , y = duration)) + 
    # Add a violin plot 
  geom_violin(fill = "#5F85AE", alpha =0.2, color = NA, trim = FALSE) +

  # Add a boxplot 
  geom_boxplot(width = 0.05, fill = "white", color = "#5F85AE", outlier.shape = NA) +

  # Add jittered points 
  geom_jitter(width = 0.1, height = 0.05, color = "#5F85AE", alpha = 0.8) +

  
  # Add axis and plot labels
  labs(x = "Distribution of Duration ", y = "duration (hours)") +
  
  # Customize plot theme
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
    axis.line.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_text(size = 15),
    axis.text.y = element_blank(),
    axis.title.x = element_text(size = 20),
    axis.title.y = element_text(size = 20),
    plot.title = element_blank()) +
    coord_flip() +
    labs(tag = "B")

fig4b

ggsave(here("figures", "fig4b_pesticide_duration_exposure.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
ggsave(here("figures", "fig4b_pesticide_duration_exposure.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure 4C

Plot showing the percentages of studies using each exposure methodology (IP stands for intraperitoneal injection)

# Count the total occurrence of each route in the data set
total_route_count <- pdo %>% 
                     count(route)

# Count the proportion and percentage of each route in the data set
route_pct <- pdo %>%
  count(route) %>%
  mutate(proportion = n/sum(total_route_count$n),
         percentage = proportion*100)

# Create a bar chart with the percentage of pesticides by route of exposure on the x-axis and the routes of exposure on the y-axis
fig4c <- ggplot(route_pct, aes(x = reorder(route, percentage), y = percentage)) +
  
  # Customize the appearance of the bars
  geom_bar(stat = "identity", fill = "#5F85AE", color = "white", alpha = 0.8, position = position_dodge(0.9)) +
  
  # Add absolute count to bars
  geom_text(aes(label = n), position = position_stack(vjust = 0.5), color = "white", fontface = "bold", size = 7) +
  
  # Add percentage label to bars 
  geom_text(aes(label = paste0(round(percentage, 1), "%")), hjust = -0.2, vjust = 0.5, size = 7, fontface = "bold") +
  
  # Customize the appearance of the plot
  labs(x = "Route of Exposure", y = "Percentage") +
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
        axis.text.x = element_text(size = 20),
        axis.text.y = element_text(size = 20),
        axis.title.x = element_text(size = 20),
        axis.title.y = element_text(size = 20),
        plot.title = element_blank()) +
    coord_flip() + 
    ylim(0, 105) +
    labs(tag = "C")


fig4c

 ggsave(here("figures", "fig4c_pesticide_route_count.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "fig4c_pesticide_route_count.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure 4D

Plot showing the distribution of sample sizes used in pesticide exposure studies per group (if multiple exposure groups we calculated mean sample size per study)

count <- sum(sd$sample_size == "not reported", na.rm = TRUE)

# Print the count
print(count)
## [1] 11
# Remove rows where sample_size is not reported
sd1 <- sd[sd$sample_size != "not reported", ]

# Convert sample_size column to numeric
sd1$sample_size <- as.numeric(sd1$sample_size)


fig4d <- ggplot(sd1, aes(x = 1, y = sample_size)) +
 # Add a violin plot 
  geom_violin(fill = "#5F85AE", alpha =0.2, color = NA, trim = FALSE) +

  # Add a boxplot 
  geom_boxplot(width = 0.05, fill = "white", color = "#5F85AE", outlier.shape = NA) +

  # Add jittered points 
  geom_jitter(width = 0.1, height = 0.05, color = "#5F85AE", alpha = 0.8) +
  labs(x ="Distribution of Sample Size", y = "Sample Size") +
 theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
    axis.line.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_text(size = 20),
    axis.text.y = element_text(size = 20),
    axis.title.x = element_text(size = 20),
    axis.title.y = element_text(size = 20),
    plot.title = element_blank()) +
    scale_x_continuous(breaks = NULL, labels = NULL)  +
  coord_flip() +
  labs(tag = "D")

fig4d

 ggsave(here("figures", "fig4d_sample_sizes.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "fig4d_sample_sizes.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)


# Create aa dataframe with summary statistics
(function(data) {
  data.frame(
    mean = mean(data),
    sd = sd(data),
    median = median(data),
    first_quartile = quantile(data, 0.25),
    third_quartile = quantile(data, 0.75)
  )
})(sd1$sample_size)
##         mean      sd median first_quartile third_quartile
## 25% 16.10972 14.0275  11.65         7.2475             20

Figure 4

Summary of characteristics of selected study design elements across included studies. A) A box and violin plot illustrating the distribution of pesticide dosages used in pesticide exposure studies on zebrafish behaviour. Each individual point represents a specific exposure concentration from a given study. The box plot highlights the median value as well as the first and third quartiles, while the violin plot provides a visual representation of the dosage distribution, The dosage is illustrated on the Log10 scale. The plot shows both the highest and lowest pesticide dosages reported in each study with a waterborne exposure method. B) a box and violin plot i llustrating the distribution of pesticide durations used in pesticide exposure studies on zebrafish behaviour. Each individual point represents a specific exposure concentration from a given study. The box plot highlights the median value as well as the first and third quartiles, while the violin plot provides a visual representation of the duration distribution. The dosage is illustrated on the Log10 scale. C) a bar plot showing the percentages and counts of studies using each exposure methodology (IP stands for intraperitoneal injection and raw count is provided within each bar) in pesticide exposure studies on zebrafish behaviour. And D) a box and violin plot illustrating the distribution of sample sizes used in pesticides exposure studies on zebrafish. If multiple exposure groups were used in each study we calculated a mean sample size per study).

# Combine three plots into a single plot using a grid layout
fig4 <- ((fig4a | fig4b) / (fig4c | fig4d))  

fig4

 ggsave(here("figures", "fig4_pesticide_characteristics.pdf"), width = 25, height = 15, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "fig4_pesticide_characteristics.jpg"), width = 25, height = 15, units = "cm", scale = 2, dpi = 800)

Figure 5A

Percentages and counts of included papers on the effects of pesticides on zebrafish behaviour (raw count is provided within each bar) according to reported sex of zebrafish exposed to pesticides

# Calculate total count for each category
total_sex_count <- sd %>% count(sex)

# Calculate proportion and percentage for each category
sex_pct <- sd %>%
  count(sex) %>%
  mutate(proportion = n/sum(total_sex_count$n),
         percentage = proportion*100)

# Create a bar chart with the count  on the x-axis and behavioural class on the y-axis
fig5a <- ggplot(sex_pct, aes(x = reorder(sex, percentage), y = percentage)) +
  
  # Customize the appearance of the bars 
  geom_bar(stat = "identity", fill = "#5F85AE", color = "white", alpha = 0.8, position = position_dodge(0.9)) +
  
  # Add labels to the bars for percentage 
  geom_text(aes(label = paste0(round(percentage, 1), "%")), hjust = -0.2, vjust = 0.5, size = 7, fontface = "bold") +
  
  # Add absolute count to bars
  geom_text(aes(label = n), position = position_stack(vjust = 0.5), color = "white", fontface = "bold", size = 7) +
  
  # Add axis and plot labels 
  labs(x = "Sex of Exposure", y = "Percentage") +
  
  # Customize the plot theme 
   theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
    axis.line.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_text(size = 15),
    axis.text.y = element_text(size = 20, hjust = 1),
    axis.title.x = element_text(size = 20),
    axis.title.y = element_text(size = 20),
    plot.title = element_blank()) +
  coord_flip() + 
  ylim(0, 105) +
  labs(tag = "A")

fig5a

 ggsave(here("figures", "fig5a_total_sex_exposed.pdf"), width = 18, height = 15, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "fig5a_total_sex_exposed.jpg"), width = 18, height = 15, units = "cm", scale = 2, dpi = 800)

Figure 5B

Percentages and counts of included papers on the effects of pesticides on zebrafish behaviour (raw count is provided within each bar) according to zebrafish life stages at pesticide exposure

# Calculate total count for each category
total_count_lse <- sd %>% count(life_stage_exposure)

# Calculate proportion and percentage for each category
life_stage_pct <- sd %>%
    separate_rows(life_stage_exposure, sep = ",\\s*") %>% 
  count(life_stage_exposure) %>%
  mutate(proportion = n/sum(total_count_lse$n),
         percentage = proportion*100)

 # Create a bar chart with the count on the x-axis and life stage of exposure  on the y-axis
fig5b <- ggplot(life_stage_pct, aes(x = reorder(life_stage_exposure, percentage), y = percentage)) +
  
  # Customize the appearance of the bars 
   geom_bar(stat = "identity", fill = "#5F85AE", color = "white", alpha = 0.8, position = position_dodge(0.9)) +
  
  # Add labels to the bars for percentage 
  geom_text(aes(label = paste0(round(percentage, 1), "%")), hjust = -0.2, vjust = 0.5, size = 7, fontface = "bold") +
  
   # Add absolute count to bars
  geom_text(aes(label = n), position = position_stack(vjust = 0.5), color = "white", fontface = "bold", size = 7) +
  
  # Add axis and plot labels 
  labs( x = "Life Stage of Exposure", y = "Percentage", fontsize = 14) +
  
  # Customize the plot theme 
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
    axis.line.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_text(size = 15),
    axis.text.y = element_text(size = 20, hjust = 1),
    axis.title.x = element_text(size = 20),
    axis.title.y = element_text(size = 20),
    plot.title = element_blank()) +
  coord_flip() + 
  ylim(0, 105) +
  labs(tag = "B")

fig5b

 ggsave(here("figures", "fig5b_life_stage_exposure.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "fig5b_life_stage_exposure.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure 5C

Percentages and counts of included papers on the effects of pesticides on zebrafish behaviour (raw count is provided within each bar) according to zebrafish life stages at behavioural assessment

# Calculate total count for each category
total_count_lsb <- sd %>% count(life_stage_behaviour)

# Calculate proportion and percentage for each category
life_stage_pct <- sd %>%
  separate_rows(life_stage_behaviour, sep = ",\\s*") %>% 
  count(life_stage_behaviour) %>%
  mutate( proportion = n / sum(total_count_lsb$n),
    percentage = proportion * 100)

# Create a bar chart with the count on the x-axis and life stage of behavior on the y-axis
fig5c <- ggplot(life_stage_pct, aes(x = reorder(life_stage_behaviour, percentage), y = percentage)) +
  
  # Customize the appearance of the bars 
  geom_bar(stat = "identity", fill = "#5F85AE", color = "white", alpha = 0.8,position = position_dodge(0.9)) +
  
  # Add labels to the bars for percentage 
  geom_text(aes(label = paste0(round(percentage, 1), "%")), hjust = -0.2, vjust = 0.5, size = 7, fontface = "bold") +
  
  # Add absolute count to bars
  geom_text(aes(label = n), position = position_stack(vjust = 0.5), color = "white",fontface = "bold", size = 7) +
  
  # Add axis and plot labels 
  labs(x = "Life Stage of Behavior", y = "Percentage", fontsize = 14) +
  
  # Customize the plot theme 
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
    axis.line.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_text(size = 15),
    axis.text.y = element_text(size = 20, hjust = 1),
    axis.title.x = element_text(size = 20),
    axis.title.y = element_text(size = 20),
    plot.title = element_blank()) +
  coord_flip() + 
  ylim(0, 105) +
  labs(tag = "C")

fig5c

 ggsave(here("figures", "fig5c_life_stage_behaviour.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "fig5c_life_stage_behaviour.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure 5

Figure 5 – Summary of selected elements of zebrafish characteristics across included studies E (raw count is provided within each bar). Counts are according to A) reported sex of zebrafish exposed to pesticides, B) reported life-stage of zebrafish at which they were exposed to pesticides, and C) reported life-stage of zebrafish at which the behaviour was assessed.

# Combine three plots into a single plot using a grid layout
fig5 <- ((fig5a) / (fig5b) / (fig5c))
fig5

 ggsave(here("figures", "fig5_zebrafish_characteristics.pdf"), width = 18, height = 21, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "fig5_zebrafish_characteristics.jpg"), width = 18, height = 21, units = "cm", scale = 2, dpi = 800)

Objective 3

To identify the specific behaviours that have been investigated in pesticide exposure experiments that use zebrafish as a model.

Figure 6

Percentages of included papers on the effects of pesticides on zebrafish behaviour across behavioural classes assessed

# Calculate total count for each category
total_behaviour_class_count <- bd %>% 
  separate_rows(behavioural_class, sep = ",\\s*") %>%  
  count(behavioural_class)

# Calculate proportion and percentage for each category
behav_class_pct <- total_behaviour_class_count %>%
  mutate(proportion = n/sum(total_behaviour_class_count$n),
         percentage = proportion*100)

# Create a bar chart with the count on the x-axis and behavioural class assay on the y-axis
 fig6<-  ggplot(behav_class_pct, aes(x = reorder(behavioural_class, percentage), y = percentage)) +
    
  # Customize the appearance of the bars 
  geom_bar(stat = "identity", fill = "#5F85AE", color = "white", alpha = 0.8, position = position_dodge(0.9)) +
    
  # Add labels to the bars for percentage 
  geom_text(aes(label = paste0(round(percentage, 1), "%")), hjust = -0.2, vjust = 0.5, size = 7, fontface = "bold", color = "black") +
    
  # Add labels to the bars for absolute count  
  geom_text(aes(label = n), position = position_stack(vjust = 0.5), color = "white", size = 7, hjust = 0.5, fontface = "bold") +
    
  # Add axis and plot labels
  labs(x = "Behavioural Class", y = "Percentage") +
    
  # Customize the plot theme 
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
    axis.line.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_text(size = 20),
    axis.text.y = element_text(size = 20, hjust = 1),
    axis.title.x = element_text(size = 20),
    axis.title.y = element_text(size = 20),
    plot.title = element_blank()) +
   coord_flip() + 
   ylim(0, 50) 
   
fig6

 ggsave(here("figures", "fig6_behaviour_class_count.pdf"), width = 18, height = 9, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "fig6_behaviour_class_count.jpg"), width = 18, height = 9, units = "cm", scale = 2, dpi = 800)

Figure s8

Bar charts showing the percentage and counts of included studies according to evaluated behaviours that were under the locomotion/activity category (raw count is provided within each bar)

# Calculate count for each assay in behavioral activity 
total_behaviour_activity_count <- bd %>% 
  separate_rows(behaviour_activity, sep = ",\\s*") %>%  
  count(behaviour_activity) %>% 
  na.omit()

# Calculate proportion and percentage for each category
behav_activity_pct <- total_behaviour_activity_count %>%
  mutate(proportion = n/sum(total_behaviour_activity_count$n),
         percentage = proportion*100)

# Create a bar chart with the count on the x-axis and behavioural activity assay on the y-axis
figs8 <-  ggplot(behav_activity_pct, aes(x = reorder(behaviour_activity, n), y = percentage)) +
  
  # Customize the appearance of the bars 
  geom_bar(stat = "identity", fill = "#5F85AE", color = "white", alpha = 0.8, position = position_dodge(0.9)) +
  
 # Add labels to the bars for percentage 
  geom_text(aes(label = paste0(round(percentage, 1), "%")), hjust = -0.2, vjust = 0.5, size = 7, fontface = "bold",     color = "black") +
    
  # Add labels to the bars for absolute count  
  geom_text(aes(label = n), position = position_stack(vjust = 0.5), color = "white", size = 7, hjust = 0.5, fontface =   "bold") +
  
  # Add axis and plot labels
  labs(x = "Activity Assay", y = "Percentage") +
  
  # Customize the plot theme
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
    axis.line.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_text(size = 20),
    axis.text.y = element_text(size = 20, hjust = 1),
    axis.title.x = element_text(size = 20),
    axis.title.y = element_text(size = 20),
    plot.title = element_blank()) +
    coord_flip() +
  ylim(0, 100)

figs8

  ggsave(here("figures", "figs8_behaviour_activity.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
  ggsave(here("figures", "figs8_behaviour_activity.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s9

Bar charts showing the percentage and counts of included studies according to evaluated behaviours that were under the aggression category (raw count is provided within each bar)

# Calculate count for each assay in aggression behavior
total_behaviour_aggression_count <- bd %>% 
  separate_rows(behaviour_aggression, sep = ",\\s*") %>%  
  count(behaviour_aggression) %>% 
  na.omit()

# Calculate proportion and percentage for each category
behav_aggression_pct <- total_behaviour_aggression_count %>%
  mutate(proportion = n/sum(total_behaviour_aggression_count$n),
         percentage = proportion*100)

# Create a bar chart with the count on the x-axis and aggression behaviour assay on the y-axis
figs9 <-  ggplot(behav_aggression_pct, aes(x = reorder(behaviour_aggression, n), y = percentage)) +
  
  # Customize the appearance of the bars 
  geom_bar(stat = "identity", fill = "#5F85AE", color = "white", alpha = 0.8, position = position_dodge(0.9)) +
  
 # Add labels to the bars for percentage 
  geom_text(aes(label = paste0(round(percentage, 1), "%")), hjust = -0.2, vjust = 0.5, size = 7, fontface = "bold",     color = "black") +
    
  # Add labels to the bars for absolute count  
  geom_text(aes(label = n), position = position_stack(vjust = 0.5), color = "white", size = 7, hjust = 0.5, fontface =   "bold") +
  
  # Add axis and plot labels
  labs(x = "Aggression Behavior Assay", y = "Percentage") +
  
  # Customize the plot theme
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
    axis.line.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_text(size = 20),
    axis.text.y = element_text(size = 20 , hjust = 1),
    axis.title.x = element_text(size = 20),
    axis.title.y = element_text(size = 20),
    plot.title = element_blank()) +
    coord_flip() +
    ylim(0, 120) +
    scale_x_discrete(labels = c("Aggression with conspecific\nvideo or mirror of self"))

figs9

 ggsave(here("figures", "figs9_behaviour_aggression.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "figs9_behaviour_aggression.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s10

Bar charts showing the percentage and counts of included studies according to evaluated behaviours that were under the social category (raw count is provided within each bar)

# Calculate count for each assay in social behavior
total_behaviour_sociality_count <- bd %>% 
  separate_rows(behaviour_sociality, sep = ",\\s*") %>%  
  count(behaviour_sociality) %>% 
  na.omit()

# Calculate proportion and percentage for each category
behav_sociality_pct <- total_behaviour_sociality_count %>%
  mutate(proportion = n/sum(total_behaviour_sociality_count$n),
         percentage = proportion*100)

# Create a bar chart with the count on the x-axis and social behaviour assay on the y-axis
figs10 <-  ggplot(behav_sociality_pct, aes(x = reorder(behaviour_sociality, n), y = percentage)) +
  
  # Customize the appearance of the bars 
  geom_bar(stat = "identity", fill = "#5F85AE", color = "white", alpha = 0.8, position = position_dodge(0.9)) +
  
 # Add labels to the bars for percentage 
  geom_text(aes(label = paste0(round(percentage, 1), "%")), hjust = -0.2, vjust = 0.5, size = 7, fontface = "bold",     color = "black") +
    
  # Add labels to the bars for absolute count  
  geom_text(aes(label = n), position = position_stack(vjust = 0.5), color = "white", size = 7, hjust = 0.5, fontface =   "bold") +
  
  # Add axis and plot labels
  labs(x = "Social Behavior Assay ", y = "Percentage") +
  
  # Customize the plot theme
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
    axis.line.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_text(size = 20),
    axis.text.y = element_text(size = 20, hjust = 1),
    axis.title.x = element_text(size = 20),
    axis.title.y = element_text(size = 20),
    plot.title = element_blank()) +
    coord_flip() +
    ylim(0, 100) +
   scale_x_discrete(labels = c("Affiliation with conspecific\nmodel or video", "Affiliation with a live conspecific\nbehind a barrier", "Affiliation with conspecific where\n they are free to interact"))

figs10

 ggsave(here("figures", "figs10_behaviour_sociality.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "figs10_behaviour_sociality.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s11

Bar charts showing the percentage and counts of included studies according to evaluated behaviours that were under the foraging category (raw count is provided within each bar)

# Calculate count for each assay in foraging behavior
total_behaviour_foraging_count <- bd %>% 
  separate_rows(behaviour_foraging, sep = ",\\s*") %>%  
  count(behaviour_foraging) %>% 
  na.omit()

# Calculate proportion and percentage for each category
behav_foraging_pct <- total_behaviour_foraging_count %>%
  mutate(proportion = n/sum(total_behaviour_foraging_count$n),
         percentage = proportion*100)

# Create a bar chart with the count on the x-axis and foraging behaviour assay on the y-axis
figs11 <-  ggplot(behav_foraging_pct, aes(x = reorder(behaviour_foraging, n), y = percentage)) +
  
  # Customize the appearance of the bars 
  geom_bar(stat = "identity", fill = "#5F85AE", color = "white", alpha = 0.8, position = position_dodge(0.9)) +
  
 # Add labels to the bars for percentage 
  geom_text(aes(label = paste0(round(percentage, 1), "%")), hjust = -0.2, vjust = 0.5, size = 7, fontface = "bold",     color = "black") +
    
  # Add labels to the bars for absolute count  
  geom_text(aes(label = n), position = position_stack(vjust = 0.5), color = "white", size = 7, hjust = 0.5, fontface =   "bold") +
  
  # Add axis and plot labels
  labs(x = "Foraging Behavior Assay", y = "Percentage") +
  
  # Customize the plot theme
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
    axis.line.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_text(size = 20),
    axis.text.y = element_text(size = 20, hjust = 1),
    axis.title.x = element_text(size = 20),
    axis.title.y = element_text(size = 20),
    plot.title = element_blank()) +
    coord_flip() +
    ylim(0, 100) +
    scale_x_discrete(labels = c("Locomotor Activity\n within this context", "Olfactroy\npreference test", "Foraging on a live\nfood source", "Foraging on a not\n live food source"))


figs11

 ggsave(here("figures", "figs11_behaviour_foraging.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "figs11_behaviour_foraging.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s12

Bar charts showing the percentage and counts of included studies according to evaluated behaviours that were under the antipredator category (raw count is provided within each bar)

# Calculate count for each assay in antipredator behavior
total_behaviour_antipredator_count <- bd %>% 
  separate_rows(behaviour_antipredator, sep = ",\\s*") %>%  
  count(behaviour_antipredator) %>% 
  na.omit()

# Calculate proportion and percentage for each category
behav_antipredator_pct <- total_behaviour_antipredator_count %>%
  mutate(proportion = n/sum(total_behaviour_antipredator_count$n),
         percentage = proportion*100)

# Create a bar chart with the count on the x-axis and antipredator behaviour assay on the y-axis
figs12 <- ggplot(behav_antipredator_pct, aes(x = reorder(behaviour_antipredator, n), y = percentage)) +
  
  # Customize the appearance of the bars 
  geom_bar(stat = "identity", fill = "#5F85AE", color = "white", alpha = 0.8, position = position_dodge(0.9)) +
  
  # Add labels to the bars for percentage 
  geom_text(aes(label = paste0(round(percentage, 1), "%")), hjust = -0.2, vjust = 0.5, size = 7, fontface = "bold", color = "black") +
    
  # Add labels to the bars for absolute count  
  geom_text(aes(label = n), position = position_stack(vjust = 0.5), color = "white", size = 7, hjust = 0.5, fontface = "bold") +
  
  # Add axis and plot labels
  labs(x = "Antipredator Behavior Assay", y = "Percentage") +
  
  # Customize the plot theme
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
        axis.line.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.text.x = element_text(size = 20),
        axis.text.y = element_text(size = 20, hjust = 1),
        axis.title.x = element_text(size = 20),
        axis.title.y = element_text(size = 20),
        plot.title = element_blank()) +
        coord_flip() +
        ylim(0, 100) +
        scale_x_discrete(labels = c("Locomotor Activity\n within this context", "Response to a live predator\nbehind a barrier", "Response to a simulated\n predator"))

figs12

 ggsave(here("figures", "figs12_behaviour_antipredator.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "figs12_behaviour_antipredator.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s13

Bar charts showing the percentage and counts of included studies according to evaluated behaviours that were under the anxiety/boldness category (raw count is provided within each bar)

# Calculate count for each assay in anxiety behavior
total_behaviour_anxiety_count <- bd %>% 
  separate_rows(behaviour_anxiety, sep = ",\\s*") %>%  
  count(behaviour_anxiety) %>% 
  na.omit()

# Calculate proportion and percentage for each category
behav_anxiety_pct <- total_behaviour_anxiety_count %>%
  mutate(proportion = n/sum(total_behaviour_anxiety_count$n),
         percentage = proportion*100)

# Create a bar chart with the count on the x-axis and anxiety behavior assay on the y-axis
figs13 <- ggplot(behav_anxiety_pct, aes(x = reorder(behaviour_anxiety, n), y = percentage)) +
  
  # Customize the appearance of the bars 
  geom_bar(stat = "identity", fill = "#5F85AE", color = "white", alpha = 0.8, position = position_dodge(0.9)) +
  
  # Add labels to the bars for percentage 
  geom_text(aes(label = paste0(round(percentage, 1), "%")), hjust = -0.2, vjust = 0.5, size = 7, fontface = "bold", color = "black") +
    
  # Add labels to the bars for absolute count  
  geom_text(aes(label = n), position = position_stack(vjust = 0.5), color = "white", size = 7, hjust = 0.5, fontface = "bold") +
  
  # Add axis and plot labels
  labs(x = "Anxiety Behavior Assay", y = "Percentage") +
  
  # Customize the plot theme
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
        axis.line.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.text.x = element_text(size = 20),
        axis.text.y = element_text(size = 20, hjust = 1),
        axis.title.x = element_text(size = 20),
        axis.title.y = element_text(size = 20),
        plot.title = element_blank()) +
        coord_flip() +
        ylim(0, 80) + 
        scale_x_discrete(labels = c("Lights on-off", "Shoaling", "Locomotor Activity\n within this context", "Habituation task", "Black-white area", "Novel tank or\n exploration"))


figs13

  ggsave(here("figures", "figs13_behaviour_anxiety.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
  ggsave(here("figures", "figs13_behaviour_anxiety.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s14

Heat map plot showing counts of included papers according to combinations of evaluated behaviours and pesticide target class

# Join the behaviour details and pesticide details by "study_id"
bd_pd <- left_join(bd, pd, by = "study_id")

# Separate rows in "bd_pd" by "behavioural_class" and "pesticide_target_class" columns
bd_pd1 <- separate_rows(bd_pd, behavioural_class, sep = ",\\s*", convert = TRUE)
bd_pd1<- separate_rows(bd_pd1, pesticide_target_class, sep = ",\\s*", convert = TRUE)

# Group by "behavioural_class" and "pesticide_target_class" and summarize count
bd_pd_summary1 <- bd_pd1 %>%
  mutate(behavioural_class = str_trim(behavioural_class),
         pesticide_target_class = str_trim(pesticide_target_class)) %>%
  group_by(behavioural_class, pesticide_target_class) %>%
  summarise(count = n()) %>%
  ungroup() 

# Create a heatmap with pesticide target class on the x-axis and behavioural class on the y-axis
figs14 <- ggplot(bd_pd_summary1, aes(x = pesticide_target_class, y = behavioural_class, fill = count)) +
  
  #Create and fill each tile 
  geom_tile(color = "white") +
  scale_fill_gradient(low = "#F0F4F8", high = "#446487") +
  
  # Add labels to the bars for absolute count  
  geom_text(aes(label = count), color = "black", size = 7) + 
  
  # Add axis and plot labels
  labs(x = "Pesticide Target Class", y = "Behavioural Class", fill = "Count") +
  
  # Customize the plot theme
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
        axis.line.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.text.x = element_text(size = 20),
        axis.text.y = element_text(size = 20, hjust = 1),
        axis.title.x = element_text(size = 20),
        axis.title.y = element_text(size = 20),
        plot.title = element_blank(),
        legend.text = element_text(size= 20),
        legend.title = element_text(size = 20))


figs14

 ggsave(here("figures", "figs14_behaviour_target_class_heat_map.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "figs14_behaviour_target_class_heat_map.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s15

Heat map plot showing counts of included papers according to combinations of evaluated behaviours and pesticide chemical class (filtered for top 5 most abundant chemical classes)

# Separate rows by behavioural_class and pesticide_chemical_class columns
bd_pd2 <- separate_rows(bd_pd, behavioural_class, sep = ",\\s*", convert = TRUE)
bd_pd2 <- separate_rows(bd_pd2, pesticide_chemical_class, sep = ",", convert = TRUE)

# Get the top 3 most numerous pesticide chemical classes
bd_pd_summary2 <- bd_pd2 %>%
  mutate(behavioural_class = str_trim(behavioural_class),
         pesticide_target_class = str_trim(pesticide_chemical_class)) %>%
  group_by(behavioural_class, pesticide_chemical_class) %>%
  summarise(count = n()) %>%
  ungroup() 

top_pesticide_classes <- bd_pd_summary2 %>%
  filter(!is.na(pesticide_chemical_class)) %>%
  group_by(pesticide_chemical_class) %>%
  summarise(count = sum(count)) %>%
  ungroup() %>%
  top_n(5, count) %>% 
  pull(pesticide_chemical_class)

# Subset the data to include only the top 3 classes
bd_pd_summary_top5 <- bd_pd_summary2 %>%
  filter(pesticide_chemical_class %in% top_pesticide_classes)

# Create a heatmap with pesticide chemical class on the x-axis and behavioral class on the y-axis
figs15 <- ggplot(bd_pd_summary_top5, aes(x = pesticide_chemical_class, y = behavioural_class, fill = count)) +
  
  #Create and fill each tile 
  geom_tile(color = "white") +
  scale_fill_gradient(low = "#F0F4F8", high = "#446487") +
  
  # Add labels to the bars for absolute count 
  geom_text(aes(label = ifelse(count > 0, count, "")), color = "black", size = 7) +  
  
  # Add axis and plot labels
  labs(x = "Pesticide Chemical Class", y = "Behavioural Class", fill = "Count") +
  
  # Customize the plot theme
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
        axis.line.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.text.x = element_text(size = 20),
        axis.text.y = element_text(size = 20, hjust = 1),
        axis.title.x = element_text(size = 20),
        axis.title.y = element_text(size = 20),
        plot.title = element_blank(),
        legend.text = element_text(size= 20),
        legend.title = element_text(size = 20))

figs15

 ggsave(here("figures", "figs15_behaviour_chemical_class_heat_map.pdf"), width = 21, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "figs15_behaviour_chemical_class_heat_map.jpg"), width = 21, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s16

Heat map plot showing counts of included papers according to combinations of evaluated life stages and pesticide chemical class (filtered for top 5 most abundant chemical classes)

# Join the stydt details with pesticide details by "study_id". 
sd_pd <- left_join(sd, pd, by = "study_id")

# Separate rows in "sd_pd" by "life_stage_exposure" and "pesticide_chemical_class" columns
sd_pd1 <- separate_rows(sd_pd, life_stage_exposure, sep = ",", convert = TRUE)
sd_pd1 <- separate_rows(sd_pd1, pesticide_chemical_class, sep = ",", convert = TRUE)

# Group by "life_stage_exposure" and "pesticide_chemical_class" and summarize count
sd_pd_summary1 <- sd_pd1 %>%
  mutate(life_stage_exposure = str_trim(life_stage_exposure),
         pesticide_chemical_class = str_trim(pesticide_chemical_class)) %>%
  group_by(life_stage_exposure, pesticide_chemical_class) %>%
  summarise(count = n()) %>%
  ungroup()

top_pesticide_classes <- sd_pd_summary1 %>%
  filter(!is.na(pesticide_chemical_class)) %>%
  group_by(pesticide_chemical_class) %>%
  summarise(count = sum(count)) %>%
  ungroup() %>%
  top_n(4, count) %>%
  pull(pesticide_chemical_class)

sd_pd_summary1_top5 <- sd_pd_summary1 %>%
  filter(pesticide_chemical_class %in% top_pesticide_classes)

# Create a heatmap with pesticide target class on the x-axis and behavioural class on the y-axis
figs16 <- ggplot(sd_pd_summary1_top5, aes(x = pesticide_chemical_class, y = life_stage_exposure, fill = count)) +
  
  #Create and fill each tile
  geom_tile(color = "white") +
  scale_fill_gradient(low = "#F0F4F8", high = "#446487") +
  
  # Add labels to the bars for absolute count 
  geom_text(aes(label = ifelse(count > 0, count, "")), color = "black", size = 7) +
  
  # Add axis and plot labels
  labs(x = "Pesticide Chemical Class", y = "Life Stage Exposure", fill = "Count") +
  
  # Customize the plot theme
  theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
        axis.line.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.text.x = element_text(size = 20),
        axis.text.y = element_text(size = 20, hjust = 1),
        axis.title.x = element_text(size = 20),
        axis.title.y = element_text(size = 20),
        plot.title = element_blank(),
        legend.text = element_text(size= 20),
        legend.title = element_text(size = 20))

figs16

 ggsave(here("figures", "figs16_life_stage_chemical_class_heat_map.pdf"), width = 21, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "figs16_life_stage_chemical_class_heat_map.jpg"), width = 21, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s17

Heat map plot showing counts of included papers according to combinations of evaluated life stages and pesticide target class

# Separate rows by life_stage_exposure and pesticide_target_class columns
sd_pd2 <- separate_rows(sd_pd, life_stage_exposure, sep = ",", convert = TRUE)
sd_pd2 <- separate_rows(sd_pd2, pesticide_target_class, sep = ",", convert = TRUE)

# Group by "life_stage_exposure" and "pesticide_target_class" and summarize count
sd_pd_summary2 <- sd_pd2 %>%
  mutate(life_stage_exposure = str_trim(life_stage_exposure),
         pesticide_target_class = str_trim(pesticide_target_class)) %>%
  group_by(life_stage_exposure, pesticide_target_class) %>%
  summarise(count = n()) %>%
  ungroup()

# Create a heatmap with pesticide target class on the x-axis and life stage exposure on the y-axis
figs17 <- ggplot(sd_pd_summary2, aes(x = pesticide_target_class, y = life_stage_exposure, fill = count)) +
  
  #Create and fill each tile
  geom_tile(color = "white") +
  scale_fill_gradient(low = "#F0F4F8", high = "#446487") +
  
  # Add labels to the bars for absolute count 
  geom_text(aes(label = ifelse(count > 0, count, "")), color = "black", size = 7) +
  
  # Add axis and plot labels
  labs(x = "Pesticide Target Class", y = "Life Stage Exposure", fill = "Count") +
  
  # Customize the plot theme
 theme_minimal() +
  theme(panel.grid.major.y = element_blank(),
        axis.line.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.text.x = element_text(size = 20),
        axis.text.y = element_text(size = 20, hjust = 1),
        axis.title.x = element_text(size = 20),
        axis.title.y = element_text(size = 20),
        plot.title = element_blank(),
        legend.text = element_text(size= 20),
        legend.title = element_text(size = 20))


figs17                                     

 ggsave(here("figures", "figs17_life_stage_target_class_heat_map.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "figs17_life_stage_target_class_heat_map.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Objective 4

To examine how are authors connected between countries and how is the literature connected between and within disciplines

Figure s23

Average total citation count per year for papers included in the systematic map ## Figure s24 Average article citation per year for papers included in the systematic map ## Figure s25 Annual scientific production counts of papers included in the systematic map ## Figure s26 Most productive countries of author affiliations for papers included in the systematic map

# Perform bibliometric analysis on dataset "bib_sco"
figs24 <- biblioAnalysis(bib_sco)

# Display the plot of the analysis results
plot(figs24)

Figure s28

Thematic map based on keywords extracted from ID field (taken from Scopus bibliometric information) of papers included in the systematic map

# Set plot parameters to display a single plot with narrow margins
par(mfrow=c(1,1), mar=c(0,2,0,2))

# Generate a thematic map of the "bib_sco" dataset, using the "ID" field as the basis for the map
figs28 <- thematicMap(bib_sco, field = "ID", n = 1000, minfreq = 5, stemming = FALSE, size = 0.5, n.labels = 1, repel = TRUE)

# Display the resulting map using the "plot" function
plot(figs28$map)

 ggsave(here("figures", "figs28_thematic_map.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "figs28_thematic_map.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure 7

Heat map of world showing the country-level counts for first authors’ country of affiliation of studies investigating the impacts of pesticide exposure on zebrafish behaviour. Grey indicates no publications affiliated with a given country in our data set.

# Extract country information from the "AU1_CO" and "AU_CO" fields of the "bib_sco" dataset
bibmap <- metaTagExtraction(bib_sco, Field = "AU1_CO", sep = ";") 
bibmap <- metaTagExtraction(bibmap, Field = "AU_CO", sep = ";") 

# Create a data frame with counts of articles from each country
firstcountrycounts <- bibmap %>% 
  group_by(AU1_CO) %>% 
  count() %>% 
  filter(!is.na(AU1_CO))  

# Load world map data and remove countries with longitude >180 to make an equal projection-like map
world_map <- map_data("world") %>% 
  filter(! long > 180)

# Format country names to match regions on the world map
firstcountrycounts$region <- str_to_title(firstcountrycounts$AU1_CO)
firstcountrycounts$region[firstcountrycounts$region == "Usa"] <- "USA" 
firstcountrycounts$region[firstcountrycounts$region == "Korea"] <- "South Korea"

# Join count data with map data and set missing counts to zero
emptymap <- tibble(region = unique(world_map$region), n = rep(0,length(unique(world_map$region))))
fullmap <- left_join(emptymap, firstcountrycounts, by = "region")
fullmap$n <- fullmap$n.x + fullmap$n.y
fullmap$n[is.na(fullmap$n)] <- 0

# Create a plot of the world map with regions colored based on article counts
fig7 <- fullmap %>%
  ggplot(aes(fill = n, map_id = region)) +
  geom_map(map = world_map) +
  expand_limits(x = world_map$long, y = world_map$lat) +
  coord_map("moll") + # Mollweide projection
  theme_minimal() +
  theme(
    axis.text = element_blank(),  
    axis.title = element_blank(),  
    legend.position = "bottom",
    legend.box = "horizontal",  
    legend.box.just = "center",  
    legend.margin = margin(t = 10, unit = "pt"),  
    legend.text = element_text(size = 12), 
    legend.title = element_text(size = 15, face = "bold"),  
    legend.key.width = unit(30, "mm")  
  ) +
  scale_fill_gradient(
    low = "#ECF207", high = "#C307F2",
    name = "Score", na.value = "gray70",
    limits = c(1, 20)
    ) +
  guides(
    fill = guide_colourbar(
      barwidth = unit(180, units = "mm"),
      barheight = unit(3, units = "mm")
    )
  )

 
fig7

 ggsave(here("figures", "fig7_world_map.pdf"), width = 20, height = 11, units = "cm", scale = 2, dpi =800)
 ggsave(here("figures", "fig7_world_map.jpg"), width = 20, height = 11, units = "cm", scale = 2, dpi =800)

Figure s29

Country-level collaboration network circle plot with self-collaborations included, based on affiliation countries of the authors of papers included in the systematic map

# Extract countries from the affiliations
bib_sco2 <- metaTagExtraction(bib_sco, Field = "AU_CO", sep = ";")

# Create a network matrix of collaborations between countries
NetMatrix_country <- biblioNetwork(bib_sco2, analysis = "collaboration", network = "countries", sep = ";")

# Convert the network matrix to a standard matrix
NetMatrix_country <- as.matrix(NetMatrix_country)

# Remove the lower triangle (as this is duplication of info)
NetMatrix_country[lower.tri(NetMatrix_country)] <- 0 

# Change column and row names to title case
colnames(NetMatrix_country) <- str_to_title(colnames(NetMatrix_country))
rownames(NetMatrix_country) <- str_to_title(rownames(NetMatrix_country))

# Change "Usa" to "USA"
colnames(NetMatrix_country)[colnames(NetMatrix_country) == "Usa"] <- "USA"
rownames(NetMatrix_country)[rownames(NetMatrix_country) == "Usa"] <- "USA"

# Change "United Kingdom" to "UK" 
colnames(NetMatrix_country)[colnames(NetMatrix_country) == "United Kingdom"] <- "UK"
rownames(NetMatrix_country)[rownames(NetMatrix_country) == "United Kingdom"] <- "UK"

my.cols2 <- c(
  USA = "#e41a1c",
  Canada = "#377eb8",
  Mexico = "#4daf4a",
  Brazil = "#984ea3",
  Ecuador = "#ff7f00",
  Chile = "#ffff33",
  Philippines = "#a65628",
  China = "#f781bf",
  Korea = "#e41a1c",
  India = "#984ea3",
  Turkey = "#ff7f00",
  Romania = "#4daf4a",
  Switzerland = "#377eb8",
  Norway = "#1b9e77",
  Netherlands = "#d95f02",
  Germany = "#7570b3",
  France = "#e7298a",
  Italy = "#66a61e",
  Portugal = "#e6ab02",
  Spain = "#a6761d",
  Sweden = "#666666"
)

 

# Create a chord diagram of the network matrix
figs29 <- chordDiagram(NetMatrix_country, annotationTrack = "grid", preAllocateTracks = 1, grid.col = my.cols2)

# Add a track to label each sector with its name
circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
  xlim = get.cell.meta.data("xlim")
  ylim = get.cell.meta.data("ylim")
  sector.name = get.cell.meta.data("sector.index")
  circos.text(mean(xlim), ylim[1] + .1, sector.name, facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5))
  circos.axis(h = "top", labels.cex = 0.5, major.tick.length = 0.2, sector.index = sector.name, track.index = 2)
}, bg.border = NA)

Figure s30

Country-level collaborate network circle plot with self-collaborations excluded, based on affiliation countries of the authors of papers included in the systematic map

# Making diagnal zero to remove self citations 
diag(NetMatrix_country) <- 0

# Create a chord diagram of the network matrix         
figs30 <- chordDiagram(NetMatrix_country, annotationTrack = "grid", preAllocateTracks = 1, grid.col = my.cols2)

# Add a track to label each sector with its name
circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
  xlim = get.cell.meta.data("xlim")
  ylim = get.cell.meta.data("ylim")
  sector.name = get.cell.meta.data("sector.index")
  circos.text(mean(xlim), ylim[1] + .1, sector.name, facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5))
  circos.axis(h = "top", labels.cex = 0.5, major.tick.length = 0.2, sector.index = sector.name, track.index = 2)
}, bg.border = NA)

Figure s31

Continent-level collaborate network circle plot with self-collaborations included, based on affiliation countries of the authors of papers included in the systematic map

NetMatrix_continent <- NetMatrix_country
# Change "Usa" to "North America"
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "USA"] <- "North  \nAmerica"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "USA"] <- "North  \nAmerica"
# Change "Usa" to "North America"
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Canada"] <- "North  \nAmerica"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Canada"] <- "North  \nAmerica"
# Change "Mexico" to "North America"
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Mexico"] <- "North  \nAmerica"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Mexico"] <- "North  \nAmerica"
# Change China to Asia
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "China"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "China"] <- "Asia"
# Change India to Asia
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "India"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "India"] <- "Asia"
# Change Phillipines to Asia
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Philippines"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Philippines"] <- "Asia"
# Change "Brazil" to "South America"
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Brazil"] <- "South  \nAmerica"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Brazil"] <- "South  \nAmerica"
# Change "Ecuador" to "South America"
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Ecuador"] <- "South  \nAmerica"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Ecuador"] <- "South  \nAmerica"
# Change "Chile" to "South America"
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Chile"] <- "South  \nAmerica"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Chile"] <- "South  \nAmerica"
# Change "United Kingdom" to "Europe" 
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) =="UK"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) =="UK"] <- "Europe"
# Change "Romania" to "Europe"
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Romania"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Romania"] <- "Europe"
# Change "Germany" to "Europe"
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Germany"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Germany"] <- "Europe"
#Change "France" to "Europe"
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "France"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "France"] <- "Europe"
#Change "Spain" to "Europe"
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Spain"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Spain"] <- "Europe"
#Change "Portugal" to "Europe"
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Portugal"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Portugal"] <- "Europe"
#Change "Sweden" to "Europe"
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Sweden"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Sweden"] <- "Europe"
#Change "Italy" to "Europe"
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Italy"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Italy"] <- "Europe"
#Change "Netherlands" to "Europe"
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Netherlands"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Netherlands"] <- "Europe"
#Change "Norway" to "Europe"
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Norway"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Norway"] <- "Europe"
#Change "Switzerland" to "Europe"
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Switzerland"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Switzerland"] <- "Europe"
#Change "Czech Republic" to "Europe"
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Czech Republic"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Czech Republic"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Korea"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Korea"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Turkey"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Turkey"] <- "Europe"


# collapsing
merge_matrix <- t(rowsum(t(NetMatrix_continent), group = colnames(NetMatrix_continent), na.rm = T))
merge_matrix2 <- rowsum(merge_matrix, group = rownames(merge_matrix))


# Create a chord diagram of the network matrix
figs31 <- chordDiagram(merge_matrix2, annotationTrack = "grid", preAllocateTracks = 1)
# Add a track to label each sector with its name
circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
  xlim = get.cell.meta.data("xlim")
  ylim = get.cell.meta.data("ylim")
  sector.name = get.cell.meta.data("sector.index")
  circos.text(mean(xlim), ylim[1] + 0.2, sector.name, facing = "clockwise", niceFacing = TRUE, adj = c(0, 1))
  circos.axis(h = "top", labels.cex = 0.5, major.tick.length = 0.2, sector.index = sector.name, track.index = 2)
}, bg.border = NA)

Figure 8

A chord diagram illustration of collaborations across continents. Continents represent the location of the primary authors’ affiliated institution. Collaborations within continents are not shown.

# remove diagonal elements
diag(merge_matrix2) <- 0

# Create a chord diagram of the network matrix
fig8 <- chordDiagram(merge_matrix2, annotationTrack = "grid", preAllocateTracks = 1)

# Add a track to label each sector with its name
circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
  xlim = get.cell.meta.data("xlim")
  ylim = get.cell.meta.data("ylim")
  sector.name = get.cell.meta.data("sector.index")
  circos.text(mean(xlim), ylim[1] + 0.2, sector.name, facing = "clockwise", niceFacing = TRUE, adj = c(0, 1))
  circos.axis(h = "top", labels.cex = 0.5, major.tick.length = 0.2, sector.index = sector.name, track.index = 2)
}, bg.border = NA)

LS0tDQpUaXRsZTogIk1hcHBpbmcgdGhlIEJlaGF2aW91cmFsIEltcGFjdHMgb2YgUGVzdGljaWRlIEV4cG9zdXJlcyBvbiBaZWJyYWZpc2g6IEEgU3lzdGVtYXRpYyBFdmlkZW5jZSBNYXAgYW5kIEJpYmxpb21ldHJpYyBBbmFseXNpcyAiDQphdXRob3JzOiAiS3lsZSBNb3JyaXNvbiwgWWVmZW5nIFlhbmcsIE1hbnVlbGEgU2FudGFuYSwgTWFsZ29yYXphdGEgTGFnaXN6IGFuZCwgU2hpbmljaGkgTmFrYWdhd2EiDQpzdWJ0aXRsZTogU3VwcGxlbWVudGFsIGZpbGUgczINCm91dHB1dDogDQogIHJtZGZvcm1hdHM6OnJvYm9ib29rOg0KICAgIGNvZGVfZm9sZGluZzogc2hvdw0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0b2NfZGVwdGg6IDQNCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUNCi0tLQ0KYGBge3Igc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCnJtKGxpc3QgPSBscygpKQ0KIyBrbml0ciBzZXR0aW5nDQprbml0cjo6b3B0c19jaHVuayRzZXQoDQogIG1lc3NhZ2UgPSBGQUxTRSwNCiAgd2FybmluZyA9IEZBTFNFLCANCiAgY2FjaGUgPSBUUlVFLA0KICBlY2hvPVRSVUUNCikNCmBgYA0KDQpJbiB0aGlzIFJtYXJrZG93biB3ZSBwcm92aWRlIHRoZSBmb2xsb3dpbmcgd29ya2Zsb3c6DQoNCi0gT2JqZWN0aXZlIDAuIFRvIGludmVzdGlnYXRlIGdlbmVyYWwgbGl0ZXJhdHVyZSBjaGFyYWN0ZXJpc3RpY3Mgc3VjaCBhcyB0aW1lIHRyZW5kcyANCg0KLSBPYmplY3RpdmUgMS4gVG8gaW52ZXN0aWdhdGUgdGhlIHR5cGVzIG9mIHBlc3RpY2lkZXMgYW5kIHBlc3RpY2lkZSBjbGFzc2VzLCBib3RoIGluIHRlcm1zIG9mIHRoZSBjaGVtaWNhbCBzdHJ1Y3R1cmUgYW5kIHRhcmdldCBvcmdhbmlzbSwgdGhhdCBoYXZlIGJlZW4gdXNlZCBpbiBzdHVkaWVzIGV4YW1pbmluZyB0aGUgZWZmZWN0cyBvZiBwZXN0aWNpZGUgZXhwb3N1cmUgb24gcG9zdC1sYXJ2YWwgIHplYnJhZmlzaCBiZWhhdmlvdXINCg0KLSBPYmplY3RpdmUgMi4gVG8gY2hhcmFjdGVyaXNlIHRoZSBzdHVkeSBzZXQgdXBzIChlLmcuLCBjaGFyYWN0ZXJpc3RpY3Mgb2YgcGVzdGljaWRlcyBzdWNoIGFzIGNvbmNlbnRyYXRpb25zIGFuZCBkdXJhdGlvbiBvZiBleHBvc3VyZSBhbmQsIGNoYXJhY3RlcmlzdGljcyBvZiB6ZWJyYWZpc2ggc3VjaCBhcyBsaWZlIHN0YWdlIG9mIGV4cG9zdXJlIGFuZCBzZXgpICBoYXZlIGJlZW4gZW1wbG95ZWQgdG8gYXNzZXNzIHRoZSBlZmZlY3RzIG9mIHBlc3RpY2lkZSBleHBvc3VyZSBvbiB0aGUgYmVoYXZpb3VyIG9mIHBvc3QtbGFydmFsIHplYnJhZmlzaC4gICAgDQoNCi0gT2JqZWN0aXZlIDMuIFRvIGlkZW50aWZ5IHRoZSBleHRlbnQgdGhlIHNwZWNpZmljIGJlaGF2aW91cnMgaGF2ZSBiZWVuIGludmVzdGlnYXRlZCBpbiBwZXN0aWNpZGUgZXhwb3N1cmUgc3R1ZGllcyB0aGF0IHVzZSBwb3N0LWxhcnZhbCB6ZWJyYWZpc2ggYXMgYSBtb2RlbC4NCg0KLSBPYmplY3RpdmUgNC4gVG8gYXNzZXNzIHRoZSByZXNlYXJjaCBjb250cmlidXRpb25zIG9mIGRpZmZlcmVudCBjb3VudHJpZXMgYW5kIGNvbnRpbmVudHMgYW5kIGRlc2NyaWJlIHRoZSBsZXZlbCBvZiBjb2xsYWJvcmF0aW9uIGJldHdlZW4gYXV0aG9ycyBhbW9uZ3N0IGRpZmZlcmVudCBjb3VudHJpZXMuICAgIA0KDQojIExvYWQgcGFja2FnZXMgYW5kIERhdGEgDQoNCiMjIExvYWQgcGFja2FnZXMNCg0KYGBge3J9DQpwYWNtYW46OnBfbG9hZCh0aWR5dmVyc2UsDQogICAgICAgICAgICAgICBoZXJlLA0KICAgICAgICAgICAgICAgc3RyaW5nciwNCiAgICAgICAgICAgICAgIGtuaXRyLA0KICAgICAgICAgICAgICAgZm9ybWF0UiwNCiAgICAgICAgICAgICAgIGZvcmNhdHMsDQogICAgICAgICAgICAgICBnZ3Bsb3QyLA0KICAgICAgICAgICAgICAgaHJicnRoZW1lcywgDQogICAgICAgICAgICAgICBwYXRjaHdvcmssDQogICAgICAgICAgICAgICBwbG90bHksIA0KICAgICAgICAgICAgICAgYmlibGlvbWV0cml4LA0KICAgICAgICAgICAgICAgaWdyYXBoLCANCiAgICAgICAgICAgICAgIHRpZHlyLA0KICAgICAgICAgICAgICAgY2lyY2xpemUsDQogICAgICAgICAgICAgICBjb3dwbG90LCANCiAgICAgICAgICAgICAgIG1hcHByb2opDQpgYGANCg0KIyMgTG9hZCBkYXRhDQpBbGwgZXh0cmFjdGVkIGRhdGEgaXMgc3RvcmVkIGluIGZpdmUgc2VwYXJhdGUgLmNzdiBmaWxlcyByZXByZXNlbnRpbmcgZGlmZmVyZW50IGFzcGVjdHMgb2YgdGhlIGRhdGEgKGV4dHJhY3RlZCB2aWEgc3RydWN0dXJlZCBwcmVkZWZpbmVkIEdvb2dsZSBGb3JtcyAtIG9uZSBwZXIgdGFibGUpIA0KDQpCaWJsaW9ncmFwaGljIGRhdGEgcmVjb3JkcyBhcmUgZXhwb3J0ZWQgZnJvbSBTY29wdXMgKGluY2x1ZGluZyBjaXRlZCByZWZlcmVuY2VzIGZpZWxkKSBpbiAuYmliIGZvcm1hdCBhbmQgbG9jYWxseSBzYXZlZCBhcyBzY29wdXMuYmliICAgIA0KYGBge3J9DQojIExvYWQgZGF0YSBzZXQgY29udGFpbmluZyBiYWNrZ3JvdW5kIGluZm9ybWF0aW9uIG9uIGVhY2ggc3R1ZHkNCmJpYiA8LSByZWFkX2NzdihoZXJlKCJkYXRhIiwgInpmX3NtX2JpYmxpb21ldHJpY3MuY3N2IiksIHNraXAgPSAwKSAjIDgzIHJvd3MgOSBjb2x1bW5zIA0KDQojIExvYWQgZGF0YSBzZXQgY29udGFpbmluZyBpbmZvcm1hdGlvbiBvbiB0aGUgZGVzaWduIG9mIGVhY2ggc3R1ZHkgDQpzZCA8LSByZWFkX2NzdihoZXJlKCJkYXRhIiwiemZfc21fc3R1ZHlfZGV0YWlscy5jc3YiKSwgc2tpcCA9IDApICMgIDgzIHJvd3MgMTAgY29sdW1ucyANCg0KIyBMb2FkIGRhdGEgc2V0IGNvbnRhaW5pbmcgZGV0YWlscyBvZiBlYWNoIHBlc3RpY2lkZSB1c2VkIGluIGVhY2ggZXhwb3N1cmUgc3R1ZGllcw0KcGQgPC0gcmVhZF9jc3YoaGVyZSgiZGF0YSIsICJ6Zl9zbV9wZXN0aWNpZGVfZGV0YWlscy5jc3YiKSwgc2tpcCA9IDApICMgODMgcm93cyA5IGNvbHVtbnMgDQoNCiMgTG9hZCBkYXRhIHNldCBjb250YWluaW5nIGRldGFpbHMgb2YgZG9zYWdlIGFuZCBkdXJhdGlvbiBvZiBwZXN0aWNpZGUgZXhwb3N1cmUgDQpwZG8gPC1yZWFkX2NzdihoZXJlKCJkYXRhIiwiemZfc21fcGVzdGljaWRlX2Rvc2FnZS5jc3YiKSwgc2tpcCA9IDApICMgMTA4IHJvd3MgMTIgY29sdW1ucyANCg0KIyBMb2FkIGRhdGEgc2V0IGNvbnRhaW5pbmcgZGV0YWlscyBvZiBiZWhhdmlvcnVzIG1lYXN1cmVkIGluIHJlc3BvbnNlIHRvIHBlc3RpY2lkZSBleHBvc3VyZSANCmJkIDwtIHJlYWRfY3N2KGhlcmUoImRhdGEiLCAiemZfc21fYmVoYXZpb3VyX2RldGFpbHMuY3N2IiksIHNraXAgPSAwKSAjIDgzIHJvd3MgMTMgY29sdW1ucyANCg0KIyBMb2FkIGJpYmxpb21ldHJpYyBpbmZvcm1hdGlvbiBleHRyYWN0ZWQgZnJvbSBzY29wdXMgDQpiaWJfc2NvIDwtIGNvbnZlcnQyZGYoaGVyZSgiZGF0YSIsInNjb3B1cy5iaWIiKSwgZGJzb3VyY2UgPSAic2NvcHVzIiwgZm9ybWF0ID0gImJpYnRleCIpICMgNzkgcm93cyAzOCBjb2x1bW5zIA0KYGBgDQoNCiMgT2JqZWN0aXZlIDANClRvIGludmVzdGlnYXRlIGdlbmVyYWwgbGl0ZXJhdHVyZSBjaGFyYWN0ZXJpc3RpY3Mgc3VjaCBhcyB0aW1lIHRyZW5kcw0KDQojIyBGaWd1cmUgMg0KQ3VycmVudCB0aW1lIHRyZW5kcyBvZiBhcnRpY2xlcyBpbnZlc3RpZ2F0aW5nIHRoZSBpbXBhY3RzIG9mIHBlc3RpY2lkZSBleHBvc3VyZSBvbiB6ZWJyYWZpc2ggYmVoYXZpb3VyDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBDb3VudCB0aGUgbnVtYmVyIG9mIGFydGljbGVzIGJ5IHllYXINCmZpZzEgPC0gYmliICU+JQ0KICBjb3VudChwdWJsaWNhdGlvbl95ZWFyKSAlPiUNCiAgDQogICMgQ3JlYXRlIGEgYmFyIGNoYXJ0IHdpdGggcHVibGljYXRpb24geWVhciBvbiB4LWF4aXMgYW5kIGNvdW50IG9uIHktYXhpcw0KICBnZ3Bsb3QoYWVzKHggPSBwdWJsaWNhdGlvbl95ZWFyLCB5ID0gbikpICsNCiAgDQogICMgQ3VzdG9taXplIHRoZSBhcHBlYXJhbmNlIG9mIHRoZSBiYXJzDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gIiM1Rjg1QUUiLCBjb2xvciA9ICJ3aGl0ZSIsIGFscGhhID0gMC44LCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSkpICsNCiAgDQogICMgQWRkIGxhYmVscyB0byB0aGUgYmFycw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCBmb250ZmFjZSA9ICJib2xkIiwgY29sb3IgPSAid2hpdGUiLCBzaXplID0gNSwgaGp1c3QgPSAwLjUpICsNCiAgDQogICMgQ3VzdG9taXplIHRoZSBhcHBlYXJhbmNlIG9mIHRoZSBwbG90DQogIHRoZW1lX21pbmltYWwoKSArDQogIGxhYnMoeCA9ICJZZWFyIiwgeSA9ICJBcnRpY2xlIENvdW50IikgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBmYWNlID0gImJvbGQiKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCBzaXplID0gMTUpLA0KICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIpLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2LCBmYWNlID0gImJvbGQiKSkNCiANCg0KZmlnMQ0KIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzJfdGltZV90cmVuZHMucGRmIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzJfdGltZV90cmVuZHMuanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KYGBgDQoNCiMgIE9iamVjdGl2ZSAxDQpUbyBpbnZlc3RpZ2F0ZSB0aGUgdHlwZXMgb2YgcGVzdGljaWRlcyBhbmQgcGVzdGljaWRlIGNsYXNzZXMsIGJvdGggaW4gdGVybXMgb2YgY2hlbWljYWwgYW5kIHRhcmdldCwgdGhhdCBoYXZlIGJlZW4gdXNlZCBpbiBleHBlcmltZW50cyBleGFtaW5pbmcgdGhlIGVmZmVjdHMgb2YgcGVzdGljaWRlIGV4cG9zdXJlIG9uIHplYnJhZmlzaCBiZWhhdmlvdXIuDQoNCiMjIEZpZ3VyZSAzQQ0KUGVyY2VudGFnZXMgYW5kIGNvdW50cyBvZiBpbmNsdWRlZCBwYXBlcnMgb24gdGhlIGVmZmVjdHMgb2YgcGVzdGljaWRlcyBvbiB6ZWJyYWZpc2ggYmVoYXZpb3VyIChyYXcgY291bnQgaXMgcHJvdmlkZWQgd2l0aGluIGVhY2ggYmFyKSBhY2NvcmRpbmcgdG8gaW5kaXZpZHVhbCBwZXN0aWNpZGVzICjigJxvdGhlcuKAnSBpcyBhIHRvdGFsIGZvciBhbGwgcGVzdGljaWRlcyB3aXRoIGEgcHVibGljYXRpb24gY291bnQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHR3bykNCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTB9DQojIFNlcGFyYXRlIHJvd3Mgd2l0aCBtdWx0aXBsZSBwZXN0aWNpZGVzLCBjb3VudCB0aGVpciBvY2N1cnJlbmNlLCBhbmQgY29tYmluZWQgYWxsIHBlc3RpY2lkZSB0aGF0IG9jY3VyZWQgb25jZSBhcyAib3RoZXIiDQp0b3RhbF9wZXN0aWNpZGVfY291bnQgPC0gcGQgJT4lDQogIHNlcGFyYXRlX3Jvd3MocGVzdGljaWRlX2ludmVzdGlnYXRlZCwgc2VwID0gIiwgIikgJT4lDQogIGNvdW50KHBlc3RpY2lkZV9pbnZlc3RpZ2F0ZWQpICU+JQ0KICBtdXRhdGUocGVzdGljaWRlX2ludmVzdGlnYXRlZCA9IGlmZWxzZShuPD0gMiwgIm90aGVyIiwgYXMuY2hhcmFjdGVyKHBlc3RpY2lkZV9pbnZlc3RpZ2F0ZWQpKSkgJT4lDQogICMgIm90aGVyIiBpbmNsdWRlcyB0cmlhbWVmb24sIHB5cmlwcm94eWZlbiwgaW1pZGFjbG9wcmlkLCBmaXByb25pbCwgZGllbGRyaW4sIGRpYXppbm9uLCBERFQsIGN5cGVybWV0aHJpbiwgdHJpYm90eWx0aW4sIHRlcmJ1dHlsYXppbmUsIHNvZGl1bSBmbHVyaWRlLCBweXJpbWV0aG9uaWwsIHB5cmFjbG9zdHJvYmluLCBwcm9waWNvbmF6b2xlLCBwcm9jaGxvcmF6LCBwYXJhdGhpb24sIHBhY2xvYnV0YXpvbCwgbW9ub2NvdG9waG9zLCBtZXRoeWxiZW56b2F0ZSwgbWV0aHlsYmVuem9hdGUsIG1ldGhvbXlsLCBtZWNyb3Byb3AsIGxpbnVyb24sIGVuZG9zdWxmYW4sIGRpdXJvbiwgZGlmZW5vY29uYXpvbGUsIGRpY2FtYmEsICAgY3lwcm9kaW5pbCwgY2hsb3JvdGhhbG9uaWwsIGNhcmJvZnVyYW4sIGNhcmJhcnlsLCBicm9mbGFuaWxpZGUgYW5kIGJvc2NhbGlkLiANCiAgDQogIGdyb3VwX2J5KHBlc3RpY2lkZV9pbnZlc3RpZ2F0ZWQpICU+JQ0KICBzdW1tYXJpc2UobiA9IHN1bShuKSkNCg0KICAjIENhbGN1bGF0ZSBwZXN0aWNpZGUgY291bnQgYXMgYSBwZXJjZW50YWdlIA0KICBwZXN0aWNpZGVfcGN0IDwtIHRvdGFsX3Blc3RpY2lkZV9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuL3N1bSh0b3RhbF9wZXN0aWNpZGVfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbioxMDApDQogIA0KIyBDcmVhdGUgYSBiYXIgY2hhcnQgd2l0aCB0aGUgY291bnQgb2YgcGVzdGljaWRlcyBvbiB0aGUgeC1heGlzIGFuZCBwZXN0aWNpZGVzIG9uIHRoZSB5LWF4aXMNCmZpZzNhIDwtICBnZ3Bsb3QocGVzdGljaWRlX3BjdCwgYWVzKHggPSByZW9yZGVyKHBlc3RpY2lkZV9pbnZlc3RpZ2F0ZWQsIG4pLCB5ID0gcGVyY2VudGFnZSkpICsNCiAgDQogICMgQ3VzdG9taXplIHRoZSBhcHBlYXJhbmNlIG9mIHRoZSBiYXJzDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gIiM1Rjg1QUUiLCBjb2xvciA9ICJ3aGl0ZSIsIGFscGhhID0gMC44LCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSkpICsNCiAgDQogICMgQWRkIGxhYmVscyB0byB0aGUgYmFycyBmb3IgYWJzb2x1dGUgY291bnQgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksIGNvbG9yID0gIndoaXRlIiwgZm9udGZhY2UgPSAiYm9sZCIsIHNpemUgPSA3KSArDQogIA0KDQogICMgQWRkIGxhYmVscyB0byB0aGUgYmFycyBmb3IgcGVyY2VudGFnZSANCiBnZW9tX3RleHQoZGF0YSA9IHBlc3RpY2lkZV9wY3QsIGFlcyhsYWJlbCA9IHBhc3RlMChyb3VuZChwZXJjZW50YWdlLDEpLCAiJSIpKSwgDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC45KSwgaGp1c3QgPSAtMC4xLCBzaXplID0gNywgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICANCiAgIyBDdXN0b21pemUgdGhlIGFwcGVhcmFuY2Ugb2YgdGhlIHBsb3QNCiAgbGFicyh4ID0gIlBlc3RpY2lkZSIsIHkgPSAiUGVyY2VudGFnZSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwNCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksDQogICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICAgICAgICBjb29yZF9mbGlwKCkgKw0KICAgICAgICB5bGltKDAsNTApICsNCiAgICAgICAgbGFicyh0YWcgPSAiQSIpDQoNCg0KZmlnM2ENCiAgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnM2FfcGVzdGljaWRlX2NvdW50LnBkZiIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiAgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnM2FfcGVzdGljaWRlX2NvdW50LmpwZyIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCg0KYGBgDQoNCiMjIEZpZ3VyZSAzQiANClBlcmNlbnRhZ2VzIGFuZCBjb3VudHMgb2YgaW5jbHVkZWQgcGFwZXJzIG9uIHRoZSBlZmZlY3RzIG9mIHBlc3RpY2lkZXMgb24gemVicmFmaXNoIGJlaGF2aW91ciAocmF3IGNvdW50IGlzIHByb3ZpZGVkIHdpdGhpbiBlYWNoIGJhcikgYWNjb3JkaW5nIHRvIHRhcmdldCBjbGFzc2VzIG9mIHBlc3RpY2lkZXMNCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTB9DQojIFNlcGFyYXRlIHJvd3Mgd2l0aCBtdWx0aXBsZSBwZXN0aWNpZGVzIGFuZCBjb3VudCB0aGVpciBvY2N1cnJlbmNlDQp0b3RhbF90YXJnZXRfY2xhc3NfY291bnQgPC0gcGQgJT4lDQogIHNlcGFyYXRlX3Jvd3MocGVzdGljaWRlX3RhcmdldF9jbGFzcywgc2VwID0gIixcXHMqIikgJT4lICANCiAgY291bnQocGVzdGljaWRlX3RhcmdldF9jbGFzcykgDQoNCiMgQ2FsY3VsYXRlIHRhcmdldCBjbGFzcyBjb3VudCBhcyBhIHBlcmNlbnRhZ2UgDQogIHRhcmdldF9jbGFzc19wY3QgPC0gdG90YWxfdGFyZ2V0X2NsYXNzX2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4vc3VtKHRvdGFsX3RhcmdldF9jbGFzc19jb3VudCRuKSwNCiAgICAgICAgIHBlcmNlbnRhZ2UgPSBwcm9wb3J0aW9uKjEwMCkNCiAgDQojIENyZWF0ZSBhIGJhciBjaGFydCB3aXRoIHRoZSBjb3VudCBvZiB0YXJnZXQgY2xhc3NlcyAgb24gdGhlIHgtYXhpcyBhbmQgcGVzdGljaWRlcyB0YXJnZXQgY2xhc3MgIG9uIHRoZSB5LWF4aXMNCmZpZzNiIDwtIGdncGxvdCh0YXJnZXRfY2xhc3NfcGN0LCBhZXMocmVvcmRlcihwZXN0aWNpZGVfdGFyZ2V0X2NsYXNzLCBuKSwgeSA9IHBlcmNlbnRhZ2UpKSArDQogIA0KICAjIEN1c3RvbWl6ZSB0aGUgYXBwZWFyYW5jZSBvZiB0aGUgYmFycw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICIjNUY4NUFFIiwgY29sb3IgPSAid2hpdGUiLCBhbHBoYSA9IDAuOCwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpKSArIA0KICANCiAgIyBBZGQgbGFiZWxzIHRvIHRoZSBiYXJzIGZvciBhYnNvbHV0ZSBjb3VudA0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCBjb2xvciA9ICJ3aGl0ZSIsIGZvbnRmYWNlID0gImJvbGQiLCBzaXplID0gNykgKw0KICANCiAgIyBBZGQgbGFiZWxzIHRvIHRoZSBiYXJzIGZvciBwZXJjZW50YWdlIA0KIGdlb21fdGV4dChkYXRhID0gdGFyZ2V0X2NsYXNzX3BjdCwgYWVzKGxhYmVsID0gcGFzdGUwKHJvdW5kKHBlcmNlbnRhZ2UsIDEpLCAiJSIpKSwgDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC45KSwgaGp1c3QgPSAtMC4yLCBzaXplID0gNywgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICAgIA0KICAjIEN1c3RvbWl6ZSB0aGUgYXBwZWFyYW5jZSBvZiB0aGUgcGxvdA0KICBsYWJzKHggPSAiUGVzdGljaWRlIFRhcmdldCBDbGFzcyIsIHkgPSAiUGVyY2VudGFnZSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICAgIGNvb3JkX2ZsaXAoKSArDQogICAgeWxpbSgwLCA4MCkgKw0KICAgIGxhYnModGFnID0gIkIiKQ0KDQoNCmZpZzNiDQogZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnM2JfcGVzdGljaWRlX3RhcmdldF9jb3VudC5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQogZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnM2JfcGVzdGljaWRlX3RhcmdldF9jb3VudC5qcGciKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQoNCmBgYA0KDQojIyBGaWd1cmUgM0MgDQpQZXJjZW50YWdlcyBhbmQgY291bnRzIG9mIGluY2x1ZGVkIHBhcGVycyBvbiB0aGUgZWZmZWN0cyBvZiBwZXN0aWNpZGVzIG9uIHplYnJhZmlzaCBiZWhhdmlvdXIgKHJhdyBjb3VudCBpcyBwcm92aWRlZCB3aXRoaW4gZWFjaCBiYXIpIGFjY29yZGluZyB0byBjaGVtaWNhbCBjbGFzc2VzIG9mIHBlc3RpY2lkZXMgKOKAnG90aGVy4oCdIGlzIGFsbCBwZXN0aWNpZGUgY2hlbWljYWwgY2xhc3NlcyB3aXRoIHB1YmxpY2F0aW9uIGNvdW50IGxlc3MgdGhhbiBvciBlcXVhbCB0byB0d28pDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBTZXBhcmF0ZSByb3dzIHdpdGggbXVsdGlwbGUgcGVzdGljaWRlcyBhbmQgY291bnQgdGhlaXIgb2NjdXJyZW5jZSwgdGhlbiBmaWx0ZXIgZm9yIGNhc2VzIHdpdGggbW9yZSB0aGFuIG9uZSBvY2N1cnJlbmNlDQp0b3RhbF9jaGVtaWNhbF9jbGFzc19jb3VudCA8LSBwZCAlPiUNCiAgc2VwYXJhdGVfcm93cyhwZXN0aWNpZGVfY2hlbWljYWxfY2xhc3MsIHNlcCA9ICIsXFxzKiIpICU+JSAgDQogIGNvdW50KHBlc3RpY2lkZV9jaGVtaWNhbF9jbGFzcykgJT4lDQogICBtdXRhdGUocGVzdGljaWRlX2NoZW1pY2FsX2NsYXNzID0gaWZlbHNlKG48PSAyLCAib3RoZXIiLCBhcy5jaGFyYWN0ZXIocGVzdGljaWRlX2NoZW1pY2FsX2NsYXNzKSkpICU+JQ0KICAjICJvdGhlciIgaW5jbHVkZXMgcHlyaWRpbmUsIHBoZW55bHVyZWEsIG5lb25pY2l0aW5vaWQsIG1vbm9jaGxvcm9iZW56ZW5zLCBhbWlub3B5cmltaWRpbmUsIHZpb2xvZ2VuLCB0cmlhbGt5bHRpbnMsIHN0cm9iaWx1cmluLCBvcmdhbm9oYWxvZ2VuLCBpbWlkYXpvbGUsIGlub3JnYW5pYyBpb25pYyBjb21wb3VuZCwgYXV4aW4sIA0KICBncm91cF9ieShwZXN0aWNpZGVfY2hlbWljYWxfY2xhc3MpICU+JQ0KICBzdW1tYXJpc2UobiA9IHN1bShuKSkNCg0KIyBDYWxjdWxhdGUgdGFyZ2V0IGNsYXNzIGNvdW50IGFzIGEgcGVyY2VudGFnZSANCiAgY2hlbWljYWxfY2xhc3NfcGN0IDwtIHRvdGFsX2NoZW1pY2FsX2NsYXNzX2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4vc3VtKHRvdGFsX2NoZW1pY2FsX2NsYXNzX2NvdW50JG4pLA0KICAgICAgICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24qMTAwKQ0KICANCiAgIyBDcmVhdGUgYSBiYXIgY2hhcnQgd2l0aCB0aGUgY291bnQgb2YgY2hlbWljYWwgY2xhc3NlcyBvbiB0aGUgeC1heGlzIGFuZCBwZXN0aWNpZGVzIGNoZW1pY2FsIGNsYXNzIG9uIHRoZSB5LWF4aXMNCiBmaWczYyA8LSAgZ2dwbG90KGNoZW1pY2FsX2NsYXNzX3BjdCwgYWVzKHggPSByZW9yZGVyKHBlc3RpY2lkZV9jaGVtaWNhbF9jbGFzcyxuKSwgeSA9IHBlcmNlbnRhZ2UpKSArDQogIA0KICAjIEN1c3RvbWl6ZSB0aGUgYXBwZWFyYW5jZSBvZiB0aGUgYmFycw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICIjNUY4NUFFIiwgY29sb3IgPSAid2hpdGUiLCBhbHBoYSA9IDAuOCwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpKSArDQogIA0KICAjIEFkZCBsYWJlbHMgdG8gdGhlIGJhcnMNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwgY29sb3IgPSAid2hpdGUiLCBmb250ZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDcpICsNCiAgDQogICANCiAgIyBBZGQgbGFiZWxzIHRvIHRoZSBiYXJzIGZvciBwZXJjZW50YWdlIA0KIGdlb21fdGV4dChkYXRhID0gY2hlbWljYWxfY2xhc3NfcGN0LCBhZXMobGFiZWwgPSBwYXN0ZTAocm91bmQocGVyY2VudGFnZSwxKSwgIiUiKSksIA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSksIGhqdXN0ID0gLTAuMiwgc2l6ZSA9IDcsIGNvbG9yID0gImJsYWNrIiwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgIA0KICAjIEN1c3RvbWl6ZSB0aGUgYXBwZWFyYW5jZSBvZiB0aGUgcGxvdA0KICBsYWJzKHggPSAiUGVzdGljaWRlIENoZW1pY2FsIENsYXNzIiwgeSA9ICJQZXJjZW50YWdlIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArDQogICAgY29vcmRfZmxpcCgpICsNCiAgICB5bGltKDAsIDQwKSArDQogICAgbGFicyh0YWcgPSAiQyIpDQogICAgDQoNCmZpZzNjDQogIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzNjX3Blc3RpY2lkZV9jaGVtaWNhbF9jb3VudC5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQogIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzNjX3Blc3RpY2lkZV9jaGVtaWNhbF9jb3VudC5qcGciKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQoNCmBgYA0KDQojIyBGaWd1cmUgMyANCkJhciBjaGFydHMgc2hvd2luZyB0aGUgcGVyY2VudGFnZXMgYW5kIGNvdW50cyBvZiBpbmNsdWRlZCBzdHVkaWVzIG9uIHRoZSBlZmZlY3RzIG9mIHBlc3RpY2lkZXMgb24gemVicmFmaXNoIGJlaGF2aW91ciAocmF3IGNvdW50IGlzIHByb3ZpZGVkIHdpdGhpbiBlYWNoIGJhcikuIENvdW50cyBhcmUgYWNjb3JkaW5nIHRvIGEpICBpbmRpdmlkdWFsIHBlc3RpY2lkZXMgKOKAnG90aGVy4oCdIGlzIGEgdG90YWwgZm9yIGFsbCBwZXN0aWNpZGVzIHdpdGggYSBwdWJsaWNhdGlvbiBjb3VudCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdHdvKSwgYikgdGFyZ2V0IGNsYXNzZXMgb2YgcGVzdGljaWRlcywgYW5kIGMpIGNoZW1pY2FsIGNsYXNzZXMgb2YgcGVzdGljaWRlcyAo4oCcb3RoZXLigJ0gaXMgYWxsIHBlc3RpY2lkZSBjaGVtaWNhbCBjbGFzc2VzIHdpdGggcHVibGljYXRpb24gY291bnQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHR3bykNCmBgYHtyLCBmaWcud2lkdGg9MjUsIGZpZy5oZWlnaHQ9MTJ9DQojIENvbWJpbmUgdGhyZWUgcGxvdHMgaW50byBhIHNpbmdsZSBwbG90IHVzaW5nIGEgZ3JpZCBsYXlvdXQNCmZpZzMgPC0gKChmaWczYSkgfCAoZmlnM2IgLyBmaWczYykpDQoNCmZpZzMNCg0KIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzNfcGVzdGljaWRlX2NvdW50X2NvbWJpbmVkLnBkZiIpLCB3aWR0aCA9IDI1LCBoZWlnaHQgPSAxMiwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWczX3Blc3RpY2lkZV9jb3VudF9jb21iaW5lZC5qcGciKSwgd2lkdGggPSAyNSwgaGVpZ2h0ID0gMTIsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQpgYGANCg0KIyBPYmplY3RpdmUgMg0KVG8gaW52ZXN0aWdhdGUgcGVzdGljaWRlIGV4cG9zdXJlIHN0dWR5IGRlc2lnbnMgc3VjaCBhcyBjb25jZW50cmF0aW9uIGFuZCBkdXJhdGlvbiBvZiBleHBvc3VyZSwgbGlmZSBzdGFnZXMgb2YgemVicmFmaXNoIHVzZWQgaW4gZWFjaCBzdHVkeSBhbmQgdGhlIHNhbXBsZSBzaXplcyB1c2VkLg0KDQoNCm1ha2luZyBkb3NhZ2VzIGNvbnNpc3RlbnQgZm9yIGRvc2FnZSBjb21wYXJpc29ucw0KYGBge3J9DQpwZG8gPC0gcGRvICU+JQ0KICAjIFJlbW92ZSByb3dzIHdpdGggTkEgdmFsdWVzDQogIGZpbHRlcighaXMubmEoZG9zYWdlX2xvd2VzdCkpICU+JQ0KICAjIENvbnZlcnQgZG9zYWdlX2xvd2VzdCB0byBudW1lcmljIGFuZCBkb3NhZ2VfbG93ZXN0X3VuaXQgdG8gY2hhcmFjdGVyDQogIG11dGF0ZShkb3NhZ2VfbG93ZXN0ID0gYXMubnVtZXJpYyhkb3NhZ2VfbG93ZXN0KSwNCiAgICAgICAgIGRvc2FnZV9sb3dlc3RfdW5pdCA9IGFzLmNoYXJhY3Rlcihkb3NhZ2VfbG93ZXN0X3VuaXQpLA0KICAgICAgICAgDQogICAgICAgICAjIFN0YW5kYXJkaXplIGRvc2FnZV91bml0X2NvbnNpc3RlbnQgYmFzZWQgb24gZG9zYWdlX2xvd2VzdF91bml0DQogICAgICAgICBkb3NhZ2VfdW5pdF9jb25zaXN0ZW50ID0gY2FzZV93aGVuKA0KICAgICAgICAgICBkb3NhZ2VfbG93ZXN0X3VuaXQgPT0gIm1nL0wiIH4gInVnL0wiLA0KICAgICAgICAgICBkb3NhZ2VfbG93ZXN0X3VuaXQgPT0gIm5nL0wiIH4gInVnL0wiLA0KICAgICAgICAgICBkb3NhZ2VfbG93ZXN0X3VuaXQgPT0gImcvTCIgfiAidWcvTCIsDQogICAgICAgICAgIGRvc2FnZV9sb3dlc3RfdW5pdCA9PSAicHBiIiB+ICJ1Zy9MIiwNCiAgICAgICAgICAgZG9zYWdlX2xvd2VzdF91bml0ID09ICJwcG0iIH4gInVnL0wiLA0KICAgICAgICAgICBUUlVFIH4gZG9zYWdlX2xvd2VzdF91bml0KSwNCiAgICAgICAgIA0KICAgICAgICAgIyBDb252ZXJ0IGRvc2FnZV9sb3dlc3QgdG8gdWcvTCBiYXNlZCBvbiBkb3NhZ2VfbG93ZXN0X3VuaXQNCiAgICAgICAgIGRvc2FnZV9sb3dlc3RfY29udmVydF91Z0wgPSBjYXNlX3doZW4oDQogICAgICAgICAgIGRvc2FnZV9sb3dlc3RfdW5pdCA9PSAibWcvTCIgfiBkb3NhZ2VfbG93ZXN0ICogMTAwMCwNCiAgICAgICAgICAgZG9zYWdlX2xvd2VzdF91bml0ID09ICJuZy9MIiB+IGRvc2FnZV9sb3dlc3QgLyAxMDAwLA0KICAgICAgICAgICBkb3NhZ2VfbG93ZXN0X3VuaXQgPT0gImcvTCIgfiBkb3NhZ2VfbG93ZXN0LzEwMDAwMDAsDQogICAgICAgICAgIGRvc2FnZV9sb3dlc3RfdW5pdCA9PSAicHBiIiB+IGRvc2FnZV9sb3dlc3QgKiAxMDAwLA0KICAgICAgICAgICBkb3NhZ2VfbG93ZXN0X3VuaXQgPT0gInBwbSIgfiBkb3NhZ2VfbG93ZXN0LzEwMDAsDQogICAgICAgICAgIFRSVUUgfiBkb3NhZ2VfbG93ZXN0KSwNCiAgICAgICAgIA0KICAgICAgICAgIyBDb252ZXJ0IGRvc2FnZV9oaWdoZXN0IHRvIG51bWVyaWMgYW5kIGRvc2FnZV9oaWdoZXN0X3VuaXQgdG8gY2hhcmFjdGVyDQogICAgICAgICBkb3NhZ2VfaGlnaGVzdCA9IGFzLm51bWVyaWMoZG9zYWdlX2hpZ2hlc3QpLA0KICAgICAgICAgDQogICAgICAgICAjIENvbnZlcnQgZG9zYWdlX2hpZ2hlc3QgdG8gdWcvTCBiYXNlZCBvbiBkb3NhZ2VfaGlnaGVzdF91bml0DQogICAgICAgICBkb3NhZ2VfaGlnaGVzdF9jb252ZXJ0X3VnTCA9IGNhc2Vfd2hlbigNCiAgICAgICAgICAgZG9zYWdlX2hpZ2hlc3RfdW5pdCA9PSAibWcvTCIgfiBkb3NhZ2VfaGlnaGVzdCAqIDEwMDAsDQogICAgICAgICAgIGRvc2FnZV9oaWdoZXN0X3VuaXQgPT0gIm5nL0wiIH4gZG9zYWdlX2hpZ2hlc3QgLyAxMDAwLA0KICAgICAgICAgICBkb3NhZ2VfaGlnaGVzdF91bml0ID09ICJnL0wiIH4gZG9zYWdlX2hpZ2hlc3QvMTAwMDAwMCwNCiAgICAgICAgICAgZG9zYWdlX2hpZ2hlc3RfdW5pdCA9PSAicHBiIiB+IGRvc2FnZV9oaWdoZXN0ICogMTAwMCwNCiAgICAgICAgICAgZG9zYWdlX2hpZ2hlc3RfdW5pdCA9PSAicHBtIiB+IGRvc2FnZV9oaWdoZXN0LzEwMDAsDQogICAgICAgICAgIFRSVUUgfiBkb3NhZ2VfaGlnaGVzdCkpDQpgYGANCg0KDQojIyBGaWd1cmUgNEENCkJveCBhbmQgdmlvbGluIHBsb3QgaWxsdXN0cmF0aW5nIHRoZSBkaXN0cmlidXRpb24gb2YgcGVzdGljaWRlIGRvc2FnZXMgdXNlZCBpbiBwZXN0aWNpZGUgZXhwb3N1cmUgc3R1ZGllcyBvbiB6ZWJyYWZpc2ggYmVoYXZpb3VyDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBQaXZvdCB0aGUgZGF0YXNldCB0byBhIGxvbmdlciBmb3JtYXQsIHNlcGFyYXRpbmcgb3V0IHRoZSBkb3NhZ2UgdHlwZSAobG93ZXN0IG9yIGhpZ2hlc3QpIGFuZCB2YWx1ZSBpbnRvIHNlcGFyYXRlIGNvbHVtbnMNCnBkb193YXRlcmJvdXJuZSA8LSBwZG8gJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gYyhkb3NhZ2VfbG93ZXN0LCBkb3NhZ2VfaGlnaGVzdCksIA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiZG9zYWdlX3R5cGUiLA0KICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gImRvc2FnZV92YWx1ZSIpICU+JSANCiAgDQogICMgRmlsdGVyIGZvciB3YXRlcmJvcm5lIHJvdXRlcyB3aXRoIGNvbnNpc3RlbnQgZG9zYWdlIHVuaXRzIGFuZCBhIGRvc2FnZSBudW1iZXIgZ3JlYXRlciB0aGFuIDENCiAgZmlsdGVyKHJvdXRlID09ICJ3YXRlcmJvdXJuZSIsIGRvc2FnZV91bml0X2NvbnNpc3RlbnQgPT0gInVnL0wiLA0KICAgICAgICAgZG9zYWdlX251bWJlciA+IDEpICU+JSAgDQogIA0KICAjIFJlbmFtZSB0aGUgZG9zYWdlIHR5cGUgY29sdW1uIGZvciBiZXR0ZXIgbGFiZWxpbmcgaW4gdGhlIHBsb3QNCiAgbXV0YXRlKGRvc2FnZV90eXBlID0gaWZfZWxzZShkb3NhZ2VfdHlwZSA9PSAiZG9zYWdlX2xvd2VzdCIsICJMb3dlc3QgRG9zYWdlIEV4cG9zZWQiLCAiSGlnaGVzdCBEb3NhZ2UgRXhwb3NlZCIpKSANCg0KIyBDcmVhdGUgdGhlIHBsb3Qgd2l0aCBkb3NhZ2UgdHlwZSAoaS5lLiwgbG93ZXN0IG9yIGhpZ2hlc3QgZG9zZSkgb24gdGhlIHgtYXhpcyBhbmQgZG9zYWdlIHZhbHVlIG9uIHRoZSB5LWF4aXMNCmZpZzRhIDwtIGdncGxvdChwZG9fd2F0ZXJib3VybmUsIGFlcyh4ID0gZG9zYWdlX3R5cGUsIHkgPSBsb2coZG9zYWdlX3ZhbHVlKSkpICsNCiAgDQogICMgQWRkIGEgdmlvbGluIHBsb3QgDQogIGdlb21fdmlvbGluKGZpbGwgPSAiIzVGODVBRSIsIGFscGhhID0wLjIsIGNvbG9yID0gTkEsIHRyaW0gPSBGQUxTRSkgKw0KDQogICMgQWRkIGEgYm94cGxvdCANCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC4wNSwgZmlsbCA9ICJ3aGl0ZSIsIGNvbG9yID0gIiM1Rjg1QUUiLCBvdXRsaWVyLnNoYXBlID0gTkEpICsNCg0KICAjIEFkZCBqaXR0ZXJlZCBwb2ludHMgLg0KICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMSwgaGVpZ2h0ID0gMC4wNSwgY29sb3IgPSAiIzVGODVBRSIsIGFscGhhID0gMC44KSArDQoNCiAgDQogICMgQWRkIGF4aXMgYW5kIHBsb3QgbGFiZWxzDQogIGxhYnModGl0bGUgPSAiV2F0ZXJib3JuZSBFeHBvc3VyZXMgYnkgRG9zYWdlIGluIHVnL0wiLCB4ID0gIldhdGVyYm9ybmUgRXhwb3N1cmUiLCB5ID0gImxvZyhEb3NhZ2UpIFt1Zy9MXSIpICsNCiAgDQogICMgQ3VzdG9taXplIHBsb3QgdGhlbWUNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICAgIGxhYnModGFnID0gIkEiKQ0KDQpmaWc0YQ0KIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzRhX3Blc3RpY2lkZV9kb3NhZ2UucGRmIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzRhX3Blc3RpY2lkZV9kb3NhZ2UuanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQpgYGANCg0KIyMgRmlndXJlIHMzIA0KQm94IGFuZCB2aW9saW4gcGxvdCBpbGx1c3RyYXRpbmcgdGhlIGRpc3RyaWJ1dGlvbiBvZiBkZWx0YW1ldGhyaW4gZG9zYWdlcyB1c2VkIGluIHBlc3RpY2lkZSBleHBvc3VyZSBzdHVkaWVzIG9uIHplYnJhZmlzaCBiZWhhdmlvdXINCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTB9DQojIFBpdm90IHRoZSBkYXRhIHNldCB0byBhIGxvbmdlciBmb3JtYXQsIHNlcGFyYXRpbmcgb3V0IHRoZSBkb3NhZ2UgdHlwZSAobG93ZXN0IG9yIGhpZ2hlc3QpIGFuZCB2YWx1ZSBpbnRvIHNlcGFyYXRlIGNvbHVtbnMNCnBkb193YXRlcmJvdXJuZV9kZWx0YW1ldGhyaW4gPC0gcGRvICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IGMoZG9zYWdlX2xvd2VzdCwgZG9zYWdlX2hpZ2hlc3QpLCANCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gImRvc2FnZV90eXBlIiwNCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJkb3NhZ2VfdmFsdWUiKSAlPiUgDQogIA0KICAjIEZpbHRlciBmb3Igd2F0ZXJib3JuZSByb3V0ZXMgd2l0aCBjb25zaXN0ZW50IGRvc2FnZSB1bml0cyBhbmQgb25seSBkZWx0YW1ldGhyaW4gcGVzdGljaWRlIGludmVzdGlnYXRlZA0KICBmaWx0ZXIocm91dGUgPT0gIndhdGVyYm91cm5lIiwgZG9zYWdlX3VuaXRfY29uc2lzdGVudCA9PSAidWcvTCIsIHBlc3RpY2lkZV9pbnZlc3RpZ2F0ZWQgPT0gImRlbHRhbWV0aHJpbiIpICU+JSANCg0KICAjIFJlbmFtZSB0aGUgZG9zYWdlIHR5cGUgY29sdW1uIGZvciBiZXR0ZXIgbGFiZWxpbmcgaW4gdGhlIHBsb3QNCiAgbXV0YXRlKGRvc2FnZV90eXBlID0gaWZfZWxzZShkb3NhZ2VfdHlwZSA9PSAiZG9zYWdlX2xvd2VzdCIsICJMb3dlc3QgRG9zYWdlIEV4cG9zZWQiLCAiSGlnaGVzdCBEb3NhZ2UgRXhwb3NlZCIpKQ0KDQojIENyZWF0ZSB0aGUgcGxvdCB3aXRoIGRvc2FnZSB0eXBlIChpLmUuLCBsb3dlc3Qgb3IgaGlnaGVzdCBkb3NlKSBvbiB0aGUgeC1heGlzIGFuZCBkb3NhZ2UgdmFsdWUgb24gdGhlIHktYXhpcw0KZmlnczMgPC0gZ2dwbG90KHBkb193YXRlcmJvdXJuZV9kZWx0YW1ldGhyaW4sIGFlcyh4ID0gZG9zYWdlX3R5cGUsIHkgPSBsb2coZG9zYWdlX3ZhbHVlKSkpICsNCiAgDQogICMgQWRkIGEgdmlvbGluIHBsb3QgDQogIGdlb21fdmlvbGluKGZpbGwgPSAiIzVGODVBRSIsIGFscGhhID0gMC4yLCBjb2xvciA9IE5BLCB0cmltID0gRkFMU0UpICsNCiAgDQogICMgQWRkIGEgYm94cGxvdCANCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC4wNSwgZmlsbCA9ICJ3aGl0ZSIsIGNvbG9yID0gIiM1Rjg1QUUiLCBvdXRsaWVyLnNoYXBlID0gTkEpICsNCiAgDQogICMgQWRkIGppdHRlcmVkIHBvaW50cw0KICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMSwgaGVpZ2h0ID0gMC4wNSwgY29sb3IgPSAiIzVGODVBRSIsIGFscGhhID0gMC41KSArDQogIA0KICAjIEFkZCBheGlzIGFuZCBwbG90IGxhYmVscw0KICBsYWJzKHRpdGxlID0gIldhdGVyYm9ybmUgRXhwb3N1cmVzIG9mIERlbHRhbWV0aHJpbiBieSBEb3NhZ2UgaW4gdWcvTCIsIHggPSAiV2F0ZXJib3VybmUgZXhwb3N1cmUiLCB5ID0gImxvZyhEb3NhZ2UpIFt1Zy9MXSIpICsNCiAgDQogICMgQ3VzdG9taXplIHBsb3QgdGhlbWUNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjAsIGhqdXN0ID0gMSksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkNCg0KZmlnczMNCiAgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczNfcGVzdGljaWRlX2Rvc2FnZV9kZWx0YW1ldGhyaW4ucGRmIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KICBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzM19wZXN0aWNpZGVfZG9zYWdlX2RlbHRhbWV0aHJpbi5qcGciKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQoNCmBgYA0KDQojIyBGaWd1cmUgczQgDQpCb3ggYW5kIHZpb2xpbiBwbG90IGlsbHVzdHJhdGluZyB0aGUgZGlzdHJpYnV0aW9uIG9mIHJvdGVub25lIGRvc2FnZXMgdXNlZCBpbiBwZXN0aWNpZGUgZXhwb3N1cmUgc3R1ZGllcyBvbiB6ZWJyYWZpc2ggYmVoYXZpb3VyDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBQaXZvdCB0aGUgZGF0YSBzZXQgdG8gYSBsb25nZXIgZm9ybWF0LCBzZXBhcmF0aW5nIG91dCB0aGUgZG9zYWdlIHR5cGUgKGxvd2VzdCBvciBoaWdoZXN0KSBhbmQgdmFsdWUgaW50byBzZXBhcmF0ZSBjb2x1bW5zDQpwZG9fd2F0ZXJib3VybmVfcm90ZW5vbmUgPC0gcGRvICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IGMoZG9zYWdlX2xvd2VzdCwgZG9zYWdlX2hpZ2hlc3QpLCANCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gImRvc2FnZV90eXBlIiwNCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJkb3NhZ2VfdmFsdWUiKSAlPiUgDQogIA0KICAjIEZpbHRlciBmb3Igd2F0ZXJib3JuZSByb3V0ZXMgd2l0aCBjb25zaXN0ZW50IGRvc2FnZSB1bml0cyBhbmQgb25seSByb3Rlbm9uZSBwZXN0aWNpZGUgaW52ZXN0aWdhdGVkDQogIGZpbHRlcihyb3V0ZSA9PSAid2F0ZXJib3VybmUiLCBkb3NhZ2VfdW5pdF9jb25zaXN0ZW50ID09ICJ1Zy9MIiwgcGVzdGljaWRlX2ludmVzdGlnYXRlZCA9PSAicm90ZW5vbmUiKSAlPiUgDQogIA0KICAjIFJlbmFtZSB0aGUgZG9zYWdlIHR5cGUgY29sdW1uIGZvciBiZXR0ZXIgbGFiZWxpbmcgaW4gdGhlIHBsb3QNCiAgbXV0YXRlKGRvc2FnZV90eXBlID0gaWZfZWxzZShkb3NhZ2VfdHlwZSA9PSAiZG9zYWdlX2xvd2VzdCIsICJMb3dlc3QgRG9zYWdlIEV4cG9zZWQiLCAiSGlnaGVzdCBEb3NhZ2UgRXhwb3NlZCIpKQ0KDQojIENyZWF0ZSB0aGUgcGxvdCB3aXRoIGRvc2FnZSB0eXBlIChpLmUuLCBsb3dlc3Qgb3IgaGlnaGVzdCBkb3NlKSBvbiB0aGUgeC1heGlzIGFuZCBkb3NhZ2UgdmFsdWUgb24gdGhlIHktYXhpcw0KZmlnczQgPC0gZ2dwbG90KHBkb193YXRlcmJvdXJuZV9yb3Rlbm9uZSwgYWVzKHggPSBkb3NhZ2VfdHlwZSwgeSA9IGxvZyhkb3NhZ2VfdmFsdWUpKSkgKw0KICANCiAgIyBBZGQgYSB2aW9saW4gcGxvdCANCiAgZ2VvbV92aW9saW4oZmlsbCA9ICIjNUY4NUFFIiwgYWxwaGEgPSAwLjMsIHRyaW0gPSBGQUxTRSwgY29sb3IgPSBOQSkgKw0KICANCiAgIyBBZGQgYSBib3hwbG90IA0KICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjA1LCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiIzVGODVBRSIsIG91dGxpZXIuc2hhcGUgPSBOQSkgKw0KICANCiAgIyBBZGQgaml0dGVyZWQgcG9pbnRzDQogIGdlb21faml0dGVyKHdpZHRoID0gMC4xLCBoZWlnaHQgPSAwLjA1LCBjb2xvciA9ICIjNUY4NUFFIiwgYWxwaGEgPSAwLjUpICsNCiAgDQogICMgQWRkIGF4aXMgYW5kIHBsb3QgbGFiZWxzDQogIGxhYnModGl0bGUgPSAiV2F0ZXJib3JuZSBFeHBvc3VyZXMgb2YgUm90ZW5vbmUgYnkgRG9zYWdlIGluIHVnL0wiLCB4ID0gIldhdGVyYm91cm5lIGV4cG9zdXJlIiwgeSA9ICJsb2coRG9zYWdlKSBbdWcvTF0iKSArDQogIA0KICAjIEN1c3RvbWl6ZSBwbG90IHRoZW1lDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwNCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwLCBoanVzdCA9IDEpLA0KICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpDQpmaWdzNA0KICAgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczRfcGVzdGljaWRlX2Rvc2FnZV9yb3Rlbm9uZS5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQogICBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzNF9wZXN0aWNpZGVfZG9zYWdlX3JvdGVub25lLmpwZyIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCg0KYGBgDQoNCiMjIEZpZ3VyZSBzNSANCkJveCBhbmQgdmlvbGluIHBsb3QgaWxsdXN0cmF0aW5nIHRoZSBkaXN0cmlidXRpb24gb2YgYXRyYXppbmUgZG9zYWdlcyB1c2VkIGluIHBlc3RpY2lkZSBleHBvc3VyZSBzdHVkaWVzIG9uIHplYnJhZmlzaCBiZWhhdmlvdXIgDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBQaXZvdCB0aGUgZGF0YSBzZXQgdG8gYSBsb25nZXIgZm9ybWF0LCBzZXBhcmF0aW5nIG91dCB0aGUgZG9zYWdlIHR5cGUgKGxvd2VzdCBvciBoaWdoZXN0KSBhbmQgdmFsdWUgaW50byBzZXBhcmF0ZSBjb2x1bW5zDQpwZG9fd2F0ZXJib3VybmVfYXRyYXppbmUgPC0gcGRvICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IGMoZG9zYWdlX2xvd2VzdCwgZG9zYWdlX2hpZ2hlc3QpLCANCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gImRvc2FnZV90eXBlIiwNCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJkb3NhZ2VfdmFsdWUiKSAlPiUgDQoNCiAgIyBGaWx0ZXIgZm9yIHdhdGVyYm9ybmUgcm91dGVzIHdpdGggY29uc2lzdGVudCBkb3NhZ2UgdW5pdHMgYW5kIG9ubHkgYXRyYXppbmUgcGVzdGljaWRlIGludmVzdGlnYXRlZA0KICBmaWx0ZXIocm91dGUgPT0gIndhdGVyYm91cm5lIiwgZG9zYWdlX3VuaXRfY29uc2lzdGVudCA9PSAidWcvTCIsIHBlc3RpY2lkZV9pbnZlc3RpZ2F0ZWQgPT0gImF0cmF6aW5lIikgJT4lICANCg0KICAjIFJlbmFtZSB0aGUgZG9zYWdlIHR5cGUgY29sdW1uIGZvciBiZXR0ZXIgbGFiZWxpbmcgaW4gdGhlIHBsb3QNCiAgbXV0YXRlKGRvc2FnZV90eXBlID0gaWZfZWxzZShkb3NhZ2VfdHlwZSA9PSAiZG9zYWdlX2xvd2VzdCIsICJMb3dlc3QgRG9zYWdlIEV4cG9zZWQiLCAiSGlnaGVzdCBEb3NhZ2UgRXhwb3NlZCIpKQ0KDQojIENyZWF0ZSB0aGUgcGxvdCB3aXRoIGRvc2FnZSB0eXBlIChpLmUuLCBsb3dlc3Qgb3IgaGlnaGVzdCBkb3NlKSBvbiB0aGUgeC1heGlzIGFuZCBkb3NhZ2UgdmFsdWUgb24gdGhlIHktYXhpcw0KZmlnczUgPC0gZ2dwbG90KHBkb193YXRlcmJvdXJuZV9hdHJhemluZSwgYWVzKHggPSBkb3NhZ2VfdHlwZSwgeSA9IGxvZyhkb3NhZ2VfdmFsdWUpKSkgKw0KDQogICMgQWRkIGEgdmlvbGluIHBsb3QgDQogIGdlb21fdmlvbGluKGZpbGwgPSAiIzVGODVBRSIsIGFscGhhID0gMC4zLCB0cmltID0gRkFMU0UsIGNvbG9yID0gIk5BIikgKw0KDQogICMgQWRkIGEgYm94cGxvdCANCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC4wNSwgZmlsbCA9ICJ3aGl0ZSIsIGNvbG9yID0gIiM1Rjg1QUUiLCBvdXRsaWVyLnNoYXBlID0gTkEpICsNCg0KICAjIEFkZCBqaXR0ZXJlZCBwb2ludHMNCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjEsIGhlaWdodCA9IDAuMDUsIGNvbG9yID0gIiM1Rjg1QUUiLCBhbHBoYSA9IDAuNSkgKw0KDQogICMgQWRkIGF4aXMgYW5kIHBsb3QgbGFiZWxzDQogIGxhYnModGl0bGUgPSAiV2F0ZXJib3JuZSBFeHBvc3VyZXMgb2YgQXRyYXppbmUgYnkgRG9zYWdlIGluIHVnL0wiLCB4ID0gIldhdGVyYm9ybmUgZXhwb3N1cmUiLCB5ID0gImxvZyhEb3NhZ2UpIFt1Zy9MXSIpICArDQoNCiAgIyBDdXN0b21pemUgcGxvdCB0aGVtZQ0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwLCBoanVzdCA9IDEpLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpDQoNCg0KZmlnczUNCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzNV9wZXN0aWNpZGVfZG9zYWdlX2F0cmF6aW5lLnBkZiIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzNV9wZXN0aWNpZGVfZG9zYWdlX2F0cmF6aW5lLmpwZyIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCmBgYA0KDQojIyBGaWd1cmUgczYgDQpCb3ggYW5kIHZpb2xpbiBwbG90IGlsbHVzdHJhdGluZyB0aGUgZGlzdHJpYnV0aW9uIG9mIGdseXBob3NhdGUgZG9zYWdlcyB1c2VkIGluIHBlc3RpY2lkZSBleHBvc3VyZSBzdHVkaWVzIG9uIHplYnJhZmlzaCBiZWhhdmlvdXIgDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBQaXZvdCB0aGUgZGF0YSBzZXQgdG8gYSBsb25nZXIgZm9ybWF0LCBzZXBhcmF0aW5nIG91dCB0aGUgZG9zYWdlIHR5cGUgKGxvd2VzdCBvciBoaWdoZXN0KSBhbmQgdmFsdWUgaW50byBzZXBhcmF0ZSBjb2x1bW5zDQpwZG9fd2F0ZXJib3VybmVfZ2x5cGhvc2F0ZSA8LSBwZG8gJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gYyhkb3NhZ2VfbG93ZXN0LCBkb3NhZ2VfaGlnaGVzdCksIA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiZG9zYWdlX3R5cGUiLA0KICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gImRvc2FnZV92YWx1ZSIpICU+JSANCiAgDQogICMgRmlsdGVyIGZvciB3YXRlcmJvcm5lIHJvdXRlcyB3aXRoIGNvbnNpc3RlbnQgZG9zYWdlIHVuaXRzIGFuZCBvbmx5IGdseXBob3NhdGUgcGVzdGljaWRlIGludmVzdGlnYXRlZA0KICBmaWx0ZXIocm91dGUgPT0gIndhdGVyYm91cm5lIiwgZG9zYWdlX3VuaXRfY29uc2lzdGVudCA9PSAidWcvTCIsIHBlc3RpY2lkZV9pbnZlc3RpZ2F0ZWQgPT0gImdseXBob3NhdGUiKSAlPiUgIA0KICANCiAgIyBSZW5hbWUgdGhlIGRvc2FnZSB0eXBlIGNvbHVtbiBmb3IgYmV0dGVyIGxhYmVsaW5nIGluIHRoZSBwbG90DQogIG11dGF0ZShkb3NhZ2VfdHlwZSA9IGlmX2Vsc2UoZG9zYWdlX3R5cGUgPT0gImRvc2FnZV9sb3dlc3QiLCAiTG93ZXN0IERvc2FnZSBFeHBvc2VkIiwgIkhpZ2hlc3QgRG9zYWdlIEV4cG9zZWQiKSkNCg0KDQojIENyZWF0ZSB0aGUgcGxvdCB3aXRoIGRvc2FnZSB0eXBlIChpLmUuLCBsb3dlc3Qgb3IgaGlnaGVzdCBkb3NlKSBvbiB0aGUgeC1heGlzIGFuZCBkb3NhZ2UgdmFsdWUgb24gdGhlIHktYXhpcw0KZmlnczYgPC0gZ2dwbG90KHBkb193YXRlcmJvdXJuZV9nbHlwaG9zYXRlLCBhZXMoeCA9IGRvc2FnZV90eXBlLCB5ID0gbG9nKGRvc2FnZV92YWx1ZSkpKSArDQogIA0KICAjIEFkZCBhIHZpb2xpbiBwbG90DQogZ2VvbV92aW9saW4oZmlsbCA9ICIjNUY4NUFFIiwgYWxwaGEgPSAwLjMsIHRyaW0gPSBGQUxTRSwgY29sb3IgPSBOQSkgKw0KICANCiAgIyBBZGQgYSBib3hwbG90DQogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuMDUsIGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICIjNUY4NUFFIiwgb3V0bGllci5zaGFwZSA9IE5BKSArDQogIA0KICAjIEFkZCBqaXR0ZXJlZCBwb2ludHMNCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjEsIGhlaWdodCA9IDAuMDUsIGNvbG9yID0gIiM1Rjg1QUUiLCBhbHBoYSA9IDAuNSkgKw0KICANCiAgIyBBZGQgYXhpcyBhbmQgcGxvdCBsYWJlbHMNCiAgbGFicyh0aXRsZSA9ICJXYXRlcmJvcm5lIEV4cG9zdXJlcyBvZiBHbHlwaG9zYXRlIGJ5IERvc2FnZSBpbiB1Zy9MIiwgeCA9ICJXYXRlcmJvdXJuZSBleHBvc3VyZSIsIHkgPSAibG9nKERvc2FnZSkgW3VnL0xdIikgICsNCiAgDQogICMgQ3VzdG9taXplIHBsb3QgdGhlbWUNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgaGp1c3QgPSAxKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQ0KDQpmaWdzNg0KIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3M2X3Blc3RpY2lkZV9kb3NhZ2VfZ2x5cGhvc2F0ZS5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQogZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczZfcGVzdGljaWRlX2Rvc2FnZV9nbHlwaG9zYXRlLmpwZyIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCg0KYGBgDQoNCiMjIEZpZ3VyZSBzNyANCkJveCBhbmQgdmlvbGluIHBsb3QgaWxsdXN0cmF0aW5nIHRoZSBkaXN0cmlidXRpb24gb2YgY2hsb3JweXJpZm9zIGRvc2FnZXMgdXNlZCBpbiBwZXN0aWNpZGUgZXhwb3N1cmUgc3R1ZGllcyBvbiB6ZWJyYWZpc2ggYmVoYXZpb3VyDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBQaXZvdCB0aGUgZGF0YSBzZXQgdG8gYSBsb25nZXIgZm9ybWF0LCBzZXBhcmF0aW5nIG91dCB0aGUgZG9zYWdlIHR5cGUgKGxvd2VzdCBvciBoaWdoZXN0KSBhbmQgdmFsdWUgaW50byBzZXBhcmF0ZSBjb2x1bW5zDQpwZG9fd2F0ZXJib3VybmVfY2hsb3JvcHlyaWZvIDwtIHBkbyAlPiUNCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKGRvc2FnZV9sb3dlc3QsIGRvc2FnZV9oaWdoZXN0KSwgDQogICAgICAgICAgICAgICBuYW1lc190byA9ICJkb3NhZ2VfdHlwZSIsDQogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiZG9zYWdlX3ZhbHVlIikgJT4lIA0KICANCiAgIyBGaWx0ZXIgZm9yIHdhdGVyYm9ybmUgcm91dGVzIHdpdGggY29uc2lzdGVudCBkb3NhZ2UgdW5pdHMgYW5kIG9ubHkgZ2x5cGhvc2F0ZSBwZXN0aWNpZGUgaW52ZXN0aWdhdGVkDQogIGZpbHRlcihyb3V0ZSA9PSAid2F0ZXJib3VybmUiLCBkb3NhZ2VfdW5pdF9jb25zaXN0ZW50ID09ICJ1Zy9MIiwgcGVzdGljaWRlX2ludmVzdGlnYXRlZCA9PSAiY2hsb3JvcHlyaWZvIikgJT4lICANCiAgDQogICMgUmVuYW1lIHRoZSBkb3NhZ2UgdHlwZSBjb2x1bW4gZm9yIGJldHRlciBsYWJlbGluZyBpbiB0aGUgcGxvdA0KICBtdXRhdGUoZG9zYWdlX3R5cGUgPSBpZl9lbHNlKGRvc2FnZV90eXBlID09ICJkb3NhZ2VfbG93ZXN0IiwgIkxvd2VzdCBEb3NhZ2UgRXhwb3NlZCIsICJIaWdoZXN0IERvc2FnZSBFeHBvc2VkIikpDQoNCiMgQ3JlYXRlIHRoZSBwbG90IHdpdGggZG9zYWdlIHR5cGUgKGkuZS4sIGxvd2VzdCBvciBoaWdoZXN0IGRvc2UpIG9uIHRoZSB4LWF4aXMgYW5kIGRvc2FnZSB2YWx1ZSBvbiB0aGUgeS1heGlzDQpmaWdzNyA8LSBnZ3Bsb3QocGRvX3dhdGVyYm91cm5lX2NobG9yb3B5cmlmbywgYWVzKHggPSBkb3NhZ2VfdHlwZSwgeSA9IGxvZyhkb3NhZ2VfdmFsdWUpKSkgKw0KICANCiAgIyBBZGQgYSB2aW9saW4gcGxvdA0KICBnZW9tX3Zpb2xpbihmaWxsID0gIiM1Rjg1QUUiLCBhbHBoYSA9IDAuMywgdHJpbSA9IEZBTFNFLCBjb2xvciA9IE5BKSArDQogIA0KICAjIEFkZCBhIGJveHBsb3QNCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC4wNSwgZmlsbCA9ICJ3aGl0ZSIsIGNvbG9yID0gIiM1Rjg1QUUiLCBvdXRsaWVyLnNoYXBlID0gTkEpICsNCiAgDQogICMgQWRkIGppdHRlcmVkIHBvaW50cw0KICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMSwgaGVpZ2h0ID0gMC4wNSwgY29sb3IgPSAiIzVGODVBRSIsIGFscGhhID0gMC41KSArDQoNCiAgIyBBZGQgYXhpcyBhbmQgcGxvdCBsYWJlbHMNCiAgbGFicyh0aXRsZSA9ICJXYXRlcmJvcm5lIEV4cG9zdXJlcyBvZiBDaGxvcm9weXJpZm9zIGJ5IERvc2FnZSBpbiB1Zy9MIiwgeCA9ICJXYXRlcmJvdXJuZSBleHBvc3VyZSIsIHkgPSAibG9nKERvc2FnZSkgW3VnL0xdIikgICsNCiAgDQogICMgQ3VzdG9taXplIHBsb3QgdGhlbWUNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgaGp1c3QgPSAxKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQ0KDQpmaWdzNw0KICBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzN19wZXN0aWNpZGVfZG9zYWdlX2NobG9yb3B5cmlmby5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQogIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3M3X3Blc3RpY2lkZV9kb3NhZ2VfY2hsb3JvcHlyaWZvLmpwZyIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCg0KYGBgDQoNCiMjIEZpZ3VyZSA0Qg0KUGxvdCBzaG93aW5nIHRoZSBkaXN0cmlidWlvbiBvZiBkdXJhdGlvbnMgb2YgcGVzdGljaWRlIGV4cG9zdXJlIHVzZWQgaW4gZWFjaCBzdHVkeSAoZmlsdGVyZWQgZm9yIHdhdGVyYm9ybmUgZXhwb3N1cmUpDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KcGRvX2R1cmF0aW9uIDwtIHBkbyAlPiUgDQogIGZpbHRlcighaXMubmEoZHVyYXRpb24pLCBkdXJhdGlvbiAhPSAibm90IHJlcG9ydGVkIikgJT4lDQogICMgQ29udmVydCBkdXJhdGlvbiB0byBudW1lcmljIGFuZCBkdXJhdGlvbl91bml0IHRvIGNoYXJhY3RlciANCiAgbXV0YXRlKGR1cmF0aW9uID0gYXMubnVtZXJpYyhkdXJhdGlvbiksDQogICAgICAgICBkdXJhdGlvbl91bml0ID0gYXMuY2hhcmFjdGVyKGR1cmF0aW9uX3VuaXQpLA0KICAgICAgICAgDQogICMgU3RhbmRhcmRpemUgZHVyYXRpb25fdW5pdF9jb25zaXN0ZW50IGJhc2VkIG9uIGRvc2FnZV91bml0IA0KICBkdXJhdGlvbl91bml0X2NvbnNpc3RlbnQgPSBjYXNlX3doZW4oDQogICAgICAgICAgZHVyYXRpb25fdW5pdCA9PSAibWludXRlcyIgfiAiaG91cnMiLA0KICAgICAgICAgIGR1cmF0aW9uX3VuaXQgPT0gImRheXMiIH4gImhvdXJzIiwNCiAgICAgICAgICBkdXJhdGlvbl91bml0ID09ICJ3ZWVrcyIgfiAiaG91cnMiLA0KICAgICAgICAgICBUUlVFIH4gZHVyYXRpb25fdW5pdCksDQogIA0KICAjIENvbnZlcnQgZHVyYXRpb24gdG8gaG91cnMgYmFzZWQgb24gZHVyYXRpb25fdW5pdA0KICANCiAgZHVyYXRpb25fY29udmVydCA9IGNhc2Vfd2hlbigNCiAgICBkdXJhdGlvbl91bml0ID09ICJtaW51dGVzIiB+IGR1cmF0aW9uKiA2MCwNCiAgICBkdXJhdGlvbl91bml0ID09ICJkYXlzIiB+IGR1cmF0aW9uLzI0LCANCiAgICBkdXJhdGlvbl91bml0ID09ICJ3ZWVrcyIgfiBkdXJhdGlvbi8xNjgsDQogICAgVFJVRSB+IGR1cmF0aW9uKSkgJT4lIA0KICBmaWx0ZXIocm91dGUgPT0gIndhdGVyYm91cm5lIikNCiAgDQoNCmZpZzRiIDwtIGdncGxvdChwZG9fZHVyYXRpb24sIGFlcyh4ID0gcm91dGUgLCB5ID0gZHVyYXRpb24pKSArIA0KICAgICMgQWRkIGEgdmlvbGluIHBsb3QgDQogIGdlb21fdmlvbGluKGZpbGwgPSAiIzVGODVBRSIsIGFscGhhID0wLjIsIGNvbG9yID0gTkEsIHRyaW0gPSBGQUxTRSkgKw0KDQogICMgQWRkIGEgYm94cGxvdCANCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC4wNSwgZmlsbCA9ICJ3aGl0ZSIsIGNvbG9yID0gIiM1Rjg1QUUiLCBvdXRsaWVyLnNoYXBlID0gTkEpICsNCg0KICAjIEFkZCBqaXR0ZXJlZCBwb2ludHMgDQogIGdlb21faml0dGVyKHdpZHRoID0gMC4xLCBoZWlnaHQgPSAwLjA1LCBjb2xvciA9ICIjNUY4NUFFIiwgYWxwaGEgPSAwLjgpICsNCg0KICANCiAgIyBBZGQgYXhpcyBhbmQgcGxvdCBsYWJlbHMNCiAgbGFicyh4ID0gIkRpc3RyaWJ1dGlvbiBvZiBEdXJhdGlvbiAiLCB5ID0gImR1cmF0aW9uIChob3VycykiKSArDQogIA0KICAjIEN1c3RvbWl6ZSBwbG90IHRoZW1lDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArDQogICAgY29vcmRfZmxpcCgpICsNCiAgICBsYWJzKHRhZyA9ICJCIikNCg0KZmlnNGINCmdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzRiX3Blc3RpY2lkZV9kdXJhdGlvbl9leHBvc3VyZS5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQpnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWc0Yl9wZXN0aWNpZGVfZHVyYXRpb25fZXhwb3N1cmUuanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQpgYGANCg0KIyMgRmlndXJlIDRDIA0KUGxvdCBzaG93aW5nIHRoZSBwZXJjZW50YWdlcyBvZiBzdHVkaWVzIHVzaW5nIGVhY2ggZXhwb3N1cmUgbWV0aG9kb2xvZ3kgKElQIHN0YW5kcyBmb3IgaW50cmFwZXJpdG9uZWFsIGluamVjdGlvbikgDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBDb3VudCB0aGUgdG90YWwgb2NjdXJyZW5jZSBvZiBlYWNoIHJvdXRlIGluIHRoZSBkYXRhIHNldA0KdG90YWxfcm91dGVfY291bnQgPC0gcGRvICU+JSANCiAgICAgICAgICAgICAgICAgICAgIGNvdW50KHJvdXRlKQ0KDQojIENvdW50IHRoZSBwcm9wb3J0aW9uIGFuZCBwZXJjZW50YWdlIG9mIGVhY2ggcm91dGUgaW4gdGhlIGRhdGEgc2V0DQpyb3V0ZV9wY3QgPC0gcGRvICU+JQ0KICBjb3VudChyb3V0ZSkgJT4lDQogIG11dGF0ZShwcm9wb3J0aW9uID0gbi9zdW0odG90YWxfcm91dGVfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbioxMDApDQoNCiMgQ3JlYXRlIGEgYmFyIGNoYXJ0IHdpdGggdGhlIHBlcmNlbnRhZ2Ugb2YgcGVzdGljaWRlcyBieSByb3V0ZSBvZiBleHBvc3VyZSBvbiB0aGUgeC1heGlzIGFuZCB0aGUgcm91dGVzIG9mIGV4cG9zdXJlIG9uIHRoZSB5LWF4aXMNCmZpZzRjIDwtIGdncGxvdChyb3V0ZV9wY3QsIGFlcyh4ID0gcmVvcmRlcihyb3V0ZSwgcGVyY2VudGFnZSksIHkgPSBwZXJjZW50YWdlKSkgKw0KICANCiAgIyBDdXN0b21pemUgdGhlIGFwcGVhcmFuY2Ugb2YgdGhlIGJhcnMNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAiIzVGODVBRSIsIGNvbG9yID0gIndoaXRlIiwgYWxwaGEgPSAwLjgsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSkgKw0KICANCiAgIyBBZGQgYWJzb2x1dGUgY291bnQgdG8gYmFycw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCBjb2xvciA9ICJ3aGl0ZSIsIGZvbnRmYWNlID0gImJvbGQiLCBzaXplID0gNykgKw0KICANCiAgIyBBZGQgcGVyY2VudGFnZSBsYWJlbCB0byBiYXJzIA0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUwKHJvdW5kKHBlcmNlbnRhZ2UsIDEpLCAiJSIpKSwgaGp1c3QgPSAtMC4yLCB2anVzdCA9IDAuNSwgc2l6ZSA9IDcsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIA0KICAjIEN1c3RvbWl6ZSB0aGUgYXBwZWFyYW5jZSBvZiB0aGUgcGxvdA0KICBsYWJzKHggPSAiUm91dGUgb2YgRXhwb3N1cmUiLCB5ID0gIlBlcmNlbnRhZ2UiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArDQogICAgY29vcmRfZmxpcCgpICsgDQogICAgeWxpbSgwLCAxMDUpICsNCiAgICBsYWJzKHRhZyA9ICJDIikNCg0KDQpmaWc0Yw0KIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzRjX3Blc3RpY2lkZV9yb3V0ZV9jb3VudC5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQogZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnNGNfcGVzdGljaWRlX3JvdXRlX2NvdW50LmpwZyIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCg0KYGBgDQoNCiMjIEZpZ3VyZSA0RCANClBsb3Qgc2hvd2luZyB0aGUgZGlzdHJpYnV0aW9uIG9mIHNhbXBsZSBzaXplcyAgdXNlZCBpbiBwZXN0aWNpZGUgZXhwb3N1cmUgc3R1ZGllcyBwZXIgZ3JvdXAgKGlmIG11bHRpcGxlIGV4cG9zdXJlIGdyb3VwcyB3ZSBjYWxjdWxhdGVkIG1lYW4gc2FtcGxlIHNpemUgcGVyIHN0dWR5KQ0KYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMH0NCmNvdW50IDwtIHN1bShzZCRzYW1wbGVfc2l6ZSA9PSAibm90IHJlcG9ydGVkIiwgbmEucm0gPSBUUlVFKQ0KDQojIFByaW50IHRoZSBjb3VudA0KcHJpbnQoY291bnQpDQoNCiMgUmVtb3ZlIHJvd3Mgd2hlcmUgc2FtcGxlX3NpemUgaXMgbm90IHJlcG9ydGVkDQpzZDEgPC0gc2Rbc2Qkc2FtcGxlX3NpemUgIT0gIm5vdCByZXBvcnRlZCIsIF0NCg0KIyBDb252ZXJ0IHNhbXBsZV9zaXplIGNvbHVtbiB0byBudW1lcmljDQpzZDEkc2FtcGxlX3NpemUgPC0gYXMubnVtZXJpYyhzZDEkc2FtcGxlX3NpemUpDQoNCg0KZmlnNGQgPC0gZ2dwbG90KHNkMSwgYWVzKHggPSAxLCB5ID0gc2FtcGxlX3NpemUpKSArDQogIyBBZGQgYSB2aW9saW4gcGxvdCANCiAgZ2VvbV92aW9saW4oZmlsbCA9ICIjNUY4NUFFIiwgYWxwaGEgPTAuMiwgY29sb3IgPSBOQSwgdHJpbSA9IEZBTFNFKSArDQoNCiAgIyBBZGQgYSBib3hwbG90IA0KICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjA1LCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiIzVGODVBRSIsIG91dGxpZXIuc2hhcGUgPSBOQSkgKw0KDQogICMgQWRkIGppdHRlcmVkIHBvaW50cyANCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjEsIGhlaWdodCA9IDAuMDUsIGNvbG9yID0gIiM1Rjg1QUUiLCBhbHBoYSA9IDAuOCkgKw0KICBsYWJzKHggPSJEaXN0cmlidXRpb24gb2YgU2FtcGxlIFNpemUiLCB5ID0gIlNhbXBsZSBTaXplIikgKw0KIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gTlVMTCwgbGFiZWxzID0gTlVMTCkgICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0YWcgPSAiRCIpDQoNCmZpZzRkDQogZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnNGRfc2FtcGxlX3NpemVzLnBkZiIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWc0ZF9zYW1wbGVfc2l6ZXMuanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQoNCiMgQ3JlYXRlIGFhIGRhdGFmcmFtZSB3aXRoIHN1bW1hcnkgc3RhdGlzdGljcw0KKGZ1bmN0aW9uKGRhdGEpIHsNCiAgZGF0YS5mcmFtZSgNCiAgICBtZWFuID0gbWVhbihkYXRhKSwNCiAgICBzZCA9IHNkKGRhdGEpLA0KICAgIG1lZGlhbiA9IG1lZGlhbihkYXRhKSwNCiAgICBmaXJzdF9xdWFydGlsZSA9IHF1YW50aWxlKGRhdGEsIDAuMjUpLA0KICAgIHRoaXJkX3F1YXJ0aWxlID0gcXVhbnRpbGUoZGF0YSwgMC43NSkNCiAgKQ0KfSkoc2QxJHNhbXBsZV9zaXplKQ0KDQpgYGANCg0KIyMgRmlndXJlIDQgDQpTdW1tYXJ5IG9mIGNoYXJhY3RlcmlzdGljcyBvZiBzZWxlY3RlZCBzdHVkeSBkZXNpZ24gZWxlbWVudHMgYWNyb3NzIGluY2x1ZGVkICBzdHVkaWVzLiBBKSBBIGJveCBhbmQgdmlvbGluIHBsb3QgaWxsdXN0cmF0aW5nIHRoZSBkaXN0cmlidXRpb24gb2YgcGVzdGljaWRlIGRvc2FnZXMgdXNlZCBpbiBwZXN0aWNpZGUgZXhwb3N1cmUgc3R1ZGllcyBvbiB6ZWJyYWZpc2ggYmVoYXZpb3VyLiBFYWNoIGluZGl2aWR1YWwgcG9pbnQgcmVwcmVzZW50cyBhIHNwZWNpZmljIGV4cG9zdXJlIGNvbmNlbnRyYXRpb24gZnJvbSBhIGdpdmVuIHN0dWR5LiBUaGUgYm94IHBsb3QgaGlnaGxpZ2h0cyB0aGUgbWVkaWFuIHZhbHVlIGFzIHdlbGwgYXMgdGhlIGZpcnN0IGFuZCB0aGlyZCBxdWFydGlsZXMsIHdoaWxlIHRoZSB2aW9saW4gcGxvdCBwcm92aWRlcyBhIHZpc3VhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZG9zYWdlIGRpc3RyaWJ1dGlvbiwgVGhlIGRvc2FnZSBpcyBpbGx1c3RyYXRlZCBvbiB0aGUgTG9nMTAgc2NhbGUuIFRoZSBwbG90IHNob3dzIGJvdGggdGhlIGhpZ2hlc3QgYW5kIGxvd2VzdCBwZXN0aWNpZGUgZG9zYWdlcyByZXBvcnRlZCBpbiBlYWNoIHN0dWR5IHdpdGggIGEgd2F0ZXJib3JuZSBleHBvc3VyZSBtZXRob2QuIEIpIGEgYm94IGFuZCB2aW9saW4gcGxvdCBpIGxsdXN0cmF0aW5nIHRoZSBkaXN0cmlidXRpb24gb2YgcGVzdGljaWRlIGR1cmF0aW9ucyB1c2VkIGluIHBlc3RpY2lkZSBleHBvc3VyZSBzdHVkaWVzIG9uIHplYnJhZmlzaCBiZWhhdmlvdXIuIEVhY2ggaW5kaXZpZHVhbCBwb2ludCByZXByZXNlbnRzIGEgc3BlY2lmaWMgZXhwb3N1cmUgY29uY2VudHJhdGlvbiBmcm9tIGEgZ2l2ZW4gc3R1ZHkuIFRoZSBib3ggcGxvdCBoaWdobGlnaHRzIHRoZSBtZWRpYW4gdmFsdWUgYXMgd2VsbCBhcyB0aGUgZmlyc3QgYW5kIHRoaXJkIHF1YXJ0aWxlcywgd2hpbGUgdGhlIHZpb2xpbiBwbG90IHByb3ZpZGVzIGEgdmlzdWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBkdXJhdGlvbiBkaXN0cmlidXRpb24uIFRoZSBkb3NhZ2UgaXMgaWxsdXN0cmF0ZWQgb24gdGhlIExvZzEwIHNjYWxlLiBDKSBhIGJhciBwbG90IHNob3dpbmcgdGhlIHBlcmNlbnRhZ2VzIGFuZCBjb3VudHMgb2Ygc3R1ZGllcyB1c2luZyBlYWNoIGV4cG9zdXJlIG1ldGhvZG9sb2d5IChJUCBzdGFuZHMgZm9yIGludHJhcGVyaXRvbmVhbCBpbmplY3Rpb24gYW5kIHJhdyBjb3VudCBpcyBwcm92aWRlZCB3aXRoaW4gZWFjaCBiYXIpIGluIHBlc3RpY2lkZSBleHBvc3VyZSBzdHVkaWVzIG9uIHplYnJhZmlzaCBiZWhhdmlvdXIuIEFuZCBEKSBhIGJveCBhbmQgdmlvbGluIHBsb3QgaWxsdXN0cmF0aW5nIHRoZSBkaXN0cmlidXRpb24gb2Ygc2FtcGxlIHNpemVzIHVzZWQgaW4gcGVzdGljaWRlcyBleHBvc3VyZSBzdHVkaWVzIG9uIHplYnJhZmlzaC4gSWYgbXVsdGlwbGUgZXhwb3N1cmUgZ3JvdXBzIHdlcmUgdXNlZCBpbiBlYWNoIHN0dWR5IHdlIGNhbGN1bGF0ZWQgYSBtZWFuIHNhbXBsZSBzaXplIHBlciBzdHVkeSkuDQpgYGB7ciwgZmlnLndpZHRoPTI1LCBmaWcuaGVpZ2h0PTE1fQ0KIyBDb21iaW5lIHRocmVlIHBsb3RzIGludG8gYSBzaW5nbGUgcGxvdCB1c2luZyBhIGdyaWQgbGF5b3V0DQpmaWc0IDwtICgoZmlnNGEgfCBmaWc0YikgLyAoZmlnNGMgfCBmaWc0ZCkpICANCg0KZmlnNA0KIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzRfcGVzdGljaWRlX2NoYXJhY3RlcmlzdGljcy5wZGYiKSwgd2lkdGggPSAyNSwgaGVpZ2h0ID0gMTUsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQogZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnNF9wZXN0aWNpZGVfY2hhcmFjdGVyaXN0aWNzLmpwZyIpLCB3aWR0aCA9IDI1LCBoZWlnaHQgPSAxNSwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCg0KYGBgDQoNCiMjIEZpZ3VyZSA1QSANClBlcmNlbnRhZ2VzIGFuZCBjb3VudHMgb2YgaW5jbHVkZWQgcGFwZXJzIG9uIHRoZSBlZmZlY3RzIG9mIHBlc3RpY2lkZXMgb24gemVicmFmaXNoIGJlaGF2aW91ciAocmF3IGNvdW50IGlzIHByb3ZpZGVkIHdpdGhpbiBlYWNoIGJhcikgYWNjb3JkaW5nIHRvIHJlcG9ydGVkIHNleCBvZiB6ZWJyYWZpc2ggZXhwb3NlZCB0byBwZXN0aWNpZGVzDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBDYWxjdWxhdGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCnRvdGFsX3NleF9jb3VudCA8LSBzZCAlPiUgY291bnQoc2V4KQ0KDQojIENhbGN1bGF0ZSBwcm9wb3J0aW9uIGFuZCBwZXJjZW50YWdlIGZvciBlYWNoIGNhdGVnb3J5DQpzZXhfcGN0IDwtIHNkICU+JQ0KICBjb3VudChzZXgpICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4vc3VtKHRvdGFsX3NleF9jb3VudCRuKSwNCiAgICAgICAgIHBlcmNlbnRhZ2UgPSBwcm9wb3J0aW9uKjEwMCkNCg0KIyBDcmVhdGUgYSBiYXIgY2hhcnQgd2l0aCB0aGUgY291bnQgIG9uIHRoZSB4LWF4aXMgYW5kIGJlaGF2aW91cmFsIGNsYXNzIG9uIHRoZSB5LWF4aXMNCmZpZzVhIDwtIGdncGxvdChzZXhfcGN0LCBhZXMoeCA9IHJlb3JkZXIoc2V4LCBwZXJjZW50YWdlKSwgeSA9IHBlcmNlbnRhZ2UpKSArDQogIA0KICAjIEN1c3RvbWl6ZSB0aGUgYXBwZWFyYW5jZSBvZiB0aGUgYmFycyANCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAiIzVGODVBRSIsIGNvbG9yID0gIndoaXRlIiwgYWxwaGEgPSAwLjgsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSkgKw0KICANCiAgIyBBZGQgbGFiZWxzIHRvIHRoZSBiYXJzIGZvciBwZXJjZW50YWdlIA0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUwKHJvdW5kKHBlcmNlbnRhZ2UsIDEpLCAiJSIpKSwgaGp1c3QgPSAtMC4yLCB2anVzdCA9IDAuNSwgc2l6ZSA9IDcsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIA0KICAjIEFkZCBhYnNvbHV0ZSBjb3VudCB0byBiYXJzDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksIGNvbG9yID0gIndoaXRlIiwgZm9udGZhY2UgPSAiYm9sZCIsIHNpemUgPSA3KSArDQogIA0KICAjIEFkZCBheGlzIGFuZCBwbG90IGxhYmVscyANCiAgbGFicyh4ID0gIlNleCBvZiBFeHBvc3VyZSIsIHkgPSAiUGVyY2VudGFnZSIpICsNCiAgDQogICMgQ3VzdG9taXplIHRoZSBwbG90IHRoZW1lIA0KICAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgaGp1c3QgPSAxKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArDQogIGNvb3JkX2ZsaXAoKSArIA0KICB5bGltKDAsIDEwNSkgKw0KICBsYWJzKHRhZyA9ICJBIikNCg0KZmlnNWENCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWc1YV90b3RhbF9zZXhfZXhwb3NlZC5wZGYiKSwgd2lkdGggPSAxOCwgaGVpZ2h0ID0gMTUsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQogZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnNWFfdG90YWxfc2V4X2V4cG9zZWQuanBnIiksIHdpZHRoID0gMTgsIGhlaWdodCA9IDE1LCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQpgYGANCg0KIyMgRmlndXJlIDVCIA0KUGVyY2VudGFnZXMgYW5kIGNvdW50cyBvZiBpbmNsdWRlZCBwYXBlcnMgb24gdGhlIGVmZmVjdHMgb2YgcGVzdGljaWRlcyBvbiB6ZWJyYWZpc2ggYmVoYXZpb3VyIChyYXcgY291bnQgaXMgcHJvdmlkZWQgd2l0aGluIGVhY2ggYmFyKSBhY2NvcmRpbmcgdG8gemVicmFmaXNoIGxpZmUgc3RhZ2VzIGF0IHBlc3RpY2lkZSBleHBvc3VyZQ0KYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMH0NCiMgQ2FsY3VsYXRlIHRvdGFsIGNvdW50IGZvciBlYWNoIGNhdGVnb3J5DQp0b3RhbF9jb3VudF9sc2UgPC0gc2QgJT4lIGNvdW50KGxpZmVfc3RhZ2VfZXhwb3N1cmUpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCmxpZmVfc3RhZ2VfcGN0IDwtIHNkICU+JQ0KICAgIHNlcGFyYXRlX3Jvd3MobGlmZV9zdGFnZV9leHBvc3VyZSwgc2VwID0gIixcXHMqIikgJT4lIA0KICBjb3VudChsaWZlX3N0YWdlX2V4cG9zdXJlKSAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuL3N1bSh0b3RhbF9jb3VudF9sc2UkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbioxMDApDQoNCiAjIENyZWF0ZSBhIGJhciBjaGFydCB3aXRoIHRoZSBjb3VudCBvbiB0aGUgeC1heGlzIGFuZCBsaWZlIHN0YWdlIG9mIGV4cG9zdXJlICBvbiB0aGUgeS1heGlzDQpmaWc1YiA8LSBnZ3Bsb3QobGlmZV9zdGFnZV9wY3QsIGFlcyh4ID0gcmVvcmRlcihsaWZlX3N0YWdlX2V4cG9zdXJlLCBwZXJjZW50YWdlKSwgeSA9IHBlcmNlbnRhZ2UpKSArDQogIA0KICAjIEN1c3RvbWl6ZSB0aGUgYXBwZWFyYW5jZSBvZiB0aGUgYmFycyANCiAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gIiM1Rjg1QUUiLCBjb2xvciA9ICJ3aGl0ZSIsIGFscGhhID0gMC44LCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSkpICsNCiAgDQogICMgQWRkIGxhYmVscyB0byB0aGUgYmFycyBmb3IgcGVyY2VudGFnZSANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChyb3VuZChwZXJjZW50YWdlLCAxKSwgIiUiKSksIGhqdXN0ID0gLTAuMiwgdmp1c3QgPSAwLjUsIHNpemUgPSA3LCBmb250ZmFjZSA9ICJib2xkIikgKw0KICANCiAgICMgQWRkIGFic29sdXRlIGNvdW50IHRvIGJhcnMNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwgY29sb3IgPSAid2hpdGUiLCBmb250ZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDcpICsNCiAgDQogICMgQWRkIGF4aXMgYW5kIHBsb3QgbGFiZWxzIA0KICBsYWJzKCB4ID0gIkxpZmUgU3RhZ2Ugb2YgRXhwb3N1cmUiLCB5ID0gIlBlcmNlbnRhZ2UiLCBmb250c2l6ZSA9IDE0KSArDQogIA0KICAjIEN1c3RvbWl6ZSB0aGUgcGxvdCB0aGVtZSANCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgaGp1c3QgPSAxKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArDQogIGNvb3JkX2ZsaXAoKSArIA0KICB5bGltKDAsIDEwNSkgKw0KICBsYWJzKHRhZyA9ICJCIikNCg0KZmlnNWINCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWc1Yl9saWZlX3N0YWdlX2V4cG9zdXJlLnBkZiIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWc1Yl9saWZlX3N0YWdlX2V4cG9zdXJlLmpwZyIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCg0KYGBgDQoNCiMjIEZpZ3VyZSA1QyANClBlcmNlbnRhZ2VzIGFuZCBjb3VudHMgb2YgaW5jbHVkZWQgcGFwZXJzIG9uIHRoZSBlZmZlY3RzIG9mIHBlc3RpY2lkZXMgb24gemVicmFmaXNoIGJlaGF2aW91ciAocmF3IGNvdW50IGlzIHByb3ZpZGVkIHdpdGhpbiBlYWNoIGJhcikgYWNjb3JkaW5nIHRvIHplYnJhZmlzaCBsaWZlIHN0YWdlcyBhdCBiZWhhdmlvdXJhbCBhc3Nlc3NtZW50DQpgYGBgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBDYWxjdWxhdGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCnRvdGFsX2NvdW50X2xzYiA8LSBzZCAlPiUgY291bnQobGlmZV9zdGFnZV9iZWhhdmlvdXIpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCmxpZmVfc3RhZ2VfcGN0IDwtIHNkICU+JQ0KICBzZXBhcmF0ZV9yb3dzKGxpZmVfc3RhZ2VfYmVoYXZpb3VyLCBzZXAgPSAiLFxccyoiKSAlPiUgDQogIGNvdW50KGxpZmVfc3RhZ2VfYmVoYXZpb3VyKSAlPiUNCiAgbXV0YXRlKCBwcm9wb3J0aW9uID0gbiAvIHN1bSh0b3RhbF9jb3VudF9sc2IkbiksDQogICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24gKiAxMDApDQoNCiMgQ3JlYXRlIGEgYmFyIGNoYXJ0IHdpdGggdGhlIGNvdW50IG9uIHRoZSB4LWF4aXMgYW5kIGxpZmUgc3RhZ2Ugb2YgYmVoYXZpb3Igb24gdGhlIHktYXhpcw0KZmlnNWMgPC0gZ2dwbG90KGxpZmVfc3RhZ2VfcGN0LCBhZXMoeCA9IHJlb3JkZXIobGlmZV9zdGFnZV9iZWhhdmlvdXIsIHBlcmNlbnRhZ2UpLCB5ID0gcGVyY2VudGFnZSkpICsNCiAgDQogICMgQ3VzdG9taXplIHRoZSBhcHBlYXJhbmNlIG9mIHRoZSBiYXJzIA0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICIjNUY4NUFFIiwgY29sb3IgPSAid2hpdGUiLCBhbHBoYSA9IDAuOCxwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSkpICsNCiAgDQogICMgQWRkIGxhYmVscyB0byB0aGUgYmFycyBmb3IgcGVyY2VudGFnZSANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChyb3VuZChwZXJjZW50YWdlLCAxKSwgIiUiKSksIGhqdXN0ID0gLTAuMiwgdmp1c3QgPSAwLjUsIHNpemUgPSA3LCBmb250ZmFjZSA9ICJib2xkIikgKw0KICANCiAgIyBBZGQgYWJzb2x1dGUgY291bnQgdG8gYmFycw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCBjb2xvciA9ICJ3aGl0ZSIsZm9udGZhY2UgPSAiYm9sZCIsIHNpemUgPSA3KSArDQogIA0KICAjIEFkZCBheGlzIGFuZCBwbG90IGxhYmVscyANCiAgbGFicyh4ID0gIkxpZmUgU3RhZ2Ugb2YgQmVoYXZpb3IiLCB5ID0gIlBlcmNlbnRhZ2UiLCBmb250c2l6ZSA9IDE0KSArDQogIA0KICAjIEN1c3RvbWl6ZSB0aGUgcGxvdCB0aGVtZSANCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgaGp1c3QgPSAxKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArDQogIGNvb3JkX2ZsaXAoKSArIA0KICB5bGltKDAsIDEwNSkgKw0KICBsYWJzKHRhZyA9ICJDIikNCg0KZmlnNWMNCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWc1Y19saWZlX3N0YWdlX2JlaGF2aW91ci5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQogZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnNWNfbGlmZV9zdGFnZV9iZWhhdmlvdXIuanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQpgYGANCg0KIyMgRmlndXJlIDUgDQpGaWd1cmUgNSDigJMgU3VtbWFyeSBvZiBzZWxlY3RlZCBlbGVtZW50cyBvZiB6ZWJyYWZpc2ggY2hhcmFjdGVyaXN0aWNzIGFjcm9zcyBpbmNsdWRlZCBzdHVkaWVzIEUgKHJhdyBjb3VudCBpcyBwcm92aWRlZCB3aXRoaW4gZWFjaCBiYXIpLiBDb3VudHMgYXJlIGFjY29yZGluZyB0byBBKSByZXBvcnRlZCBzZXggb2YgemVicmFmaXNoIGV4cG9zZWQgdG8gcGVzdGljaWRlcywgQikgcmVwb3J0ZWQgbGlmZS1zdGFnZSBvZiB6ZWJyYWZpc2ggYXQgd2hpY2ggdGhleSB3ZXJlIGV4cG9zZWQgdG8gcGVzdGljaWRlcywgYW5kIEMpIHJlcG9ydGVkIGxpZmUtc3RhZ2Ugb2YgemVicmFmaXNoIGF0IHdoaWNoIHRoZSBiZWhhdmlvdXIgd2FzIGFzc2Vzc2VkLg0KYGBge3IsIGZpZy53aWR0aD0xOCwgZmlnLmhlaWdodD0yMX0NCiMgQ29tYmluZSB0aHJlZSBwbG90cyBpbnRvIGEgc2luZ2xlIHBsb3QgdXNpbmcgYSBncmlkIGxheW91dA0KZmlnNSA8LSAoKGZpZzVhKSAvIChmaWc1YikgLyAoZmlnNWMpKQ0KZmlnNQ0KDQogZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnNV96ZWJyYWZpc2hfY2hhcmFjdGVyaXN0aWNzLnBkZiIpLCB3aWR0aCA9IDE4LCBoZWlnaHQgPSAyMSwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWc1X3plYnJhZmlzaF9jaGFyYWN0ZXJpc3RpY3MuanBnIiksIHdpZHRoID0gMTgsIGhlaWdodCA9IDIxLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KYGBgDQoNCiMgT2JqZWN0aXZlIDMNClRvIGlkZW50aWZ5IHRoZSBzcGVjaWZpYyBiZWhhdmlvdXJzIHRoYXQgaGF2ZSBiZWVuIGludmVzdGlnYXRlZCBpbiBwZXN0aWNpZGUgZXhwb3N1cmUgZXhwZXJpbWVudHMgdGhhdCB1c2UgemVicmFmaXNoIGFzIGEgbW9kZWwuDQoNCiMjIEZpZ3VyZSA2IA0KUGVyY2VudGFnZXMgb2YgaW5jbHVkZWQgcGFwZXJzIG9uIHRoZSBlZmZlY3RzIG9mIHBlc3RpY2lkZXMgb24gemVicmFmaXNoIGJlaGF2aW91ciBhY3Jvc3MgYmVoYXZpb3VyYWwgY2xhc3NlcyBhc3Nlc3NlZA0KYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMH0NCiMgQ2FsY3VsYXRlIHRvdGFsIGNvdW50IGZvciBlYWNoIGNhdGVnb3J5DQp0b3RhbF9iZWhhdmlvdXJfY2xhc3NfY291bnQgPC0gYmQgJT4lIA0KICBzZXBhcmF0ZV9yb3dzKGJlaGF2aW91cmFsX2NsYXNzLCBzZXAgPSAiLFxccyoiKSAlPiUgIA0KICBjb3VudChiZWhhdmlvdXJhbF9jbGFzcykNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0KYmVoYXZfY2xhc3NfcGN0IDwtIHRvdGFsX2JlaGF2aW91cl9jbGFzc19jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuL3N1bSh0b3RhbF9iZWhhdmlvdXJfY2xhc3NfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbioxMDApDQoNCiMgQ3JlYXRlIGEgYmFyIGNoYXJ0IHdpdGggdGhlIGNvdW50IG9uIHRoZSB4LWF4aXMgYW5kIGJlaGF2aW91cmFsIGNsYXNzIGFzc2F5IG9uIHRoZSB5LWF4aXMNCiBmaWc2PC0gIGdncGxvdChiZWhhdl9jbGFzc19wY3QsIGFlcyh4ID0gcmVvcmRlcihiZWhhdmlvdXJhbF9jbGFzcywgcGVyY2VudGFnZSksIHkgPSBwZXJjZW50YWdlKSkgKw0KICAgIA0KICAjIEN1c3RvbWl6ZSB0aGUgYXBwZWFyYW5jZSBvZiB0aGUgYmFycyANCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAiIzVGODVBRSIsIGNvbG9yID0gIndoaXRlIiwgYWxwaGEgPSAwLjgsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSkgKw0KICAgIA0KICAjIEFkZCBsYWJlbHMgdG8gdGhlIGJhcnMgZm9yIHBlcmNlbnRhZ2UgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZTAocm91bmQocGVyY2VudGFnZSwgMSksICIlIikpLCBoanVzdCA9IC0wLjIsIHZqdXN0ID0gMC41LCBzaXplID0gNywgZm9udGZhY2UgPSAiYm9sZCIsIGNvbG9yID0gImJsYWNrIikgKw0KICAgIA0KICAjIEFkZCBsYWJlbHMgdG8gdGhlIGJhcnMgZm9yIGFic29sdXRlIGNvdW50ICANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwgY29sb3IgPSAid2hpdGUiLCBzaXplID0gNywgaGp1c3QgPSAwLjUsIGZvbnRmYWNlID0gImJvbGQiKSArDQogICAgDQogICMgQWRkIGF4aXMgYW5kIHBsb3QgbGFiZWxzDQogIGxhYnMoeCA9ICJCZWhhdmlvdXJhbCBDbGFzcyIsIHkgPSAiUGVyY2VudGFnZSIpICsNCiAgICANCiAgIyBDdXN0b21pemUgdGhlIHBsb3QgdGhlbWUgDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjAsIGhqdXN0ID0gMSksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICAgY29vcmRfZmxpcCgpICsgDQogICB5bGltKDAsIDUwKSANCiAgIA0KZmlnNg0KIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzZfYmVoYXZpb3VyX2NsYXNzX2NvdW50LnBkZiIpLCB3aWR0aCA9IDE4LCBoZWlnaHQgPSA5LCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzZfYmVoYXZpb3VyX2NsYXNzX2NvdW50LmpwZyIpLCB3aWR0aCA9IDE4LCBoZWlnaHQgPSA5LCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQpgYGANCg0KDQojIyBGaWd1cmUgczggDQpCYXIgY2hhcnRzIHNob3dpbmcgdGhlIHBlcmNlbnRhZ2UgYW5kIGNvdW50cyBvZiBpbmNsdWRlZCBzdHVkaWVzIGFjY29yZGluZyB0byBldmFsdWF0ZWQgYmVoYXZpb3VycyB0aGF0IHdlcmUgdW5kZXIgdGhlIGxvY29tb3Rpb24vYWN0aXZpdHkgY2F0ZWdvcnkgKHJhdyBjb3VudCBpcyBwcm92aWRlZCB3aXRoaW4gZWFjaCBiYXIpIA0KYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMH0NCiMgQ2FsY3VsYXRlIGNvdW50IGZvciBlYWNoIGFzc2F5IGluIGJlaGF2aW9yYWwgYWN0aXZpdHkgDQp0b3RhbF9iZWhhdmlvdXJfYWN0aXZpdHlfY291bnQgPC0gYmQgJT4lIA0KICBzZXBhcmF0ZV9yb3dzKGJlaGF2aW91cl9hY3Rpdml0eSwgc2VwID0gIixcXHMqIikgJT4lICANCiAgY291bnQoYmVoYXZpb3VyX2FjdGl2aXR5KSAlPiUgDQogIG5hLm9taXQoKQ0KDQojIENhbGN1bGF0ZSBwcm9wb3J0aW9uIGFuZCBwZXJjZW50YWdlIGZvciBlYWNoIGNhdGVnb3J5DQpiZWhhdl9hY3Rpdml0eV9wY3QgPC0gdG90YWxfYmVoYXZpb3VyX2FjdGl2aXR5X2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4vc3VtKHRvdGFsX2JlaGF2aW91cl9hY3Rpdml0eV9jb3VudCRuKSwNCiAgICAgICAgIHBlcmNlbnRhZ2UgPSBwcm9wb3J0aW9uKjEwMCkNCg0KIyBDcmVhdGUgYSBiYXIgY2hhcnQgd2l0aCB0aGUgY291bnQgb24gdGhlIHgtYXhpcyBhbmQgYmVoYXZpb3VyYWwgYWN0aXZpdHkgYXNzYXkgb24gdGhlIHktYXhpcw0KZmlnczggPC0gIGdncGxvdChiZWhhdl9hY3Rpdml0eV9wY3QsIGFlcyh4ID0gcmVvcmRlcihiZWhhdmlvdXJfYWN0aXZpdHksIG4pLCB5ID0gcGVyY2VudGFnZSkpICsNCiAgDQogICMgQ3VzdG9taXplIHRoZSBhcHBlYXJhbmNlIG9mIHRoZSBiYXJzIA0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICIjNUY4NUFFIiwgY29sb3IgPSAid2hpdGUiLCBhbHBoYSA9IDAuOCwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpKSArDQogIA0KICMgQWRkIGxhYmVscyB0byB0aGUgYmFycyBmb3IgcGVyY2VudGFnZSANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChyb3VuZChwZXJjZW50YWdlLCAxKSwgIiUiKSksIGhqdXN0ID0gLTAuMiwgdmp1c3QgPSAwLjUsIHNpemUgPSA3LCBmb250ZmFjZSA9ICJib2xkIiwgICAgIGNvbG9yID0gImJsYWNrIikgKw0KICAgIA0KICAjIEFkZCBsYWJlbHMgdG8gdGhlIGJhcnMgZm9yIGFic29sdXRlIGNvdW50ICANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwgY29sb3IgPSAid2hpdGUiLCBzaXplID0gNywgaGp1c3QgPSAwLjUsIGZvbnRmYWNlID0gICAiYm9sZCIpICsNCiAgDQogICMgQWRkIGF4aXMgYW5kIHBsb3QgbGFiZWxzDQogIGxhYnMoeCA9ICJBY3Rpdml0eSBBc3NheSIsIHkgPSAiUGVyY2VudGFnZSIpICsNCiAgDQogICMgQ3VzdG9taXplIHRoZSBwbG90IHRoZW1lDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjAsIGhqdXN0ID0gMSksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICAgIGNvb3JkX2ZsaXAoKSArDQogIHlsaW0oMCwgMTAwKQ0KDQpmaWdzOA0KICBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzOF9iZWhhdmlvdXJfYWN0aXZpdHkucGRmIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KICBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzOF9iZWhhdmlvdXJfYWN0aXZpdHkuanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQpgYGANCg0KIyMgRmlndXJlIHM5IA0KQmFyIGNoYXJ0cyBzaG93aW5nIHRoZSBwZXJjZW50YWdlIGFuZCBjb3VudHMgb2YgaW5jbHVkZWQgc3R1ZGllcyBhY2NvcmRpbmcgdG8gZXZhbHVhdGVkIGJlaGF2aW91cnMgdGhhdCB3ZXJlIHVuZGVyIHRoZSBhZ2dyZXNzaW9uIGNhdGVnb3J5IChyYXcgY291bnQgaXMgcHJvdmlkZWQgd2l0aGluIGVhY2ggYmFyKQ0KYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMH0NCiMgQ2FsY3VsYXRlIGNvdW50IGZvciBlYWNoIGFzc2F5IGluIGFnZ3Jlc3Npb24gYmVoYXZpb3INCnRvdGFsX2JlaGF2aW91cl9hZ2dyZXNzaW9uX2NvdW50IDwtIGJkICU+JSANCiAgc2VwYXJhdGVfcm93cyhiZWhhdmlvdXJfYWdncmVzc2lvbiwgc2VwID0gIixcXHMqIikgJT4lICANCiAgY291bnQoYmVoYXZpb3VyX2FnZ3Jlc3Npb24pICU+JSANCiAgbmEub21pdCgpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCmJlaGF2X2FnZ3Jlc3Npb25fcGN0IDwtIHRvdGFsX2JlaGF2aW91cl9hZ2dyZXNzaW9uX2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4vc3VtKHRvdGFsX2JlaGF2aW91cl9hZ2dyZXNzaW9uX2NvdW50JG4pLA0KICAgICAgICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24qMTAwKQ0KDQojIENyZWF0ZSBhIGJhciBjaGFydCB3aXRoIHRoZSBjb3VudCBvbiB0aGUgeC1heGlzIGFuZCBhZ2dyZXNzaW9uIGJlaGF2aW91ciBhc3NheSBvbiB0aGUgeS1heGlzDQpmaWdzOSA8LSAgZ2dwbG90KGJlaGF2X2FnZ3Jlc3Npb25fcGN0LCBhZXMoeCA9IHJlb3JkZXIoYmVoYXZpb3VyX2FnZ3Jlc3Npb24sIG4pLCB5ID0gcGVyY2VudGFnZSkpICsNCiAgDQogICMgQ3VzdG9taXplIHRoZSBhcHBlYXJhbmNlIG9mIHRoZSBiYXJzIA0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICIjNUY4NUFFIiwgY29sb3IgPSAid2hpdGUiLCBhbHBoYSA9IDAuOCwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpKSArDQogIA0KICMgQWRkIGxhYmVscyB0byB0aGUgYmFycyBmb3IgcGVyY2VudGFnZSANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChyb3VuZChwZXJjZW50YWdlLCAxKSwgIiUiKSksIGhqdXN0ID0gLTAuMiwgdmp1c3QgPSAwLjUsIHNpemUgPSA3LCBmb250ZmFjZSA9ICJib2xkIiwgICAgIGNvbG9yID0gImJsYWNrIikgKw0KICAgIA0KICAjIEFkZCBsYWJlbHMgdG8gdGhlIGJhcnMgZm9yIGFic29sdXRlIGNvdW50ICANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwgY29sb3IgPSAid2hpdGUiLCBzaXplID0gNywgaGp1c3QgPSAwLjUsIGZvbnRmYWNlID0gICAiYm9sZCIpICsNCiAgDQogICMgQWRkIGF4aXMgYW5kIHBsb3QgbGFiZWxzDQogIGxhYnMoeCA9ICJBZ2dyZXNzaW9uIEJlaGF2aW9yIEFzc2F5IiwgeSA9ICJQZXJjZW50YWdlIikgKw0KICANCiAgIyBDdXN0b21pemUgdGhlIHBsb3QgdGhlbWUNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCAsIGhqdXN0ID0gMSksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICAgIGNvb3JkX2ZsaXAoKSArDQogICAgeWxpbSgwLCAxMjApICsNCiAgICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGMoIkFnZ3Jlc3Npb24gd2l0aCBjb25zcGVjaWZpY1xudmlkZW8gb3IgbWlycm9yIG9mIHNlbGYiKSkNCg0KZmlnczkNCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzOV9iZWhhdmlvdXJfYWdncmVzc2lvbi5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQogZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczlfYmVoYXZpb3VyX2FnZ3Jlc3Npb24uanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQpgYGANCg0KIyMgRmlndXJlIHMxMCANCkJhciBjaGFydHMgc2hvd2luZyB0aGUgcGVyY2VudGFnZSBhbmQgY291bnRzIG9mIGluY2x1ZGVkIHN0dWRpZXMgYWNjb3JkaW5nIHRvIGV2YWx1YXRlZCBiZWhhdmlvdXJzIHRoYXQgd2VyZSB1bmRlciB0aGUgc29jaWFsIGNhdGVnb3J5IChyYXcgY291bnQgaXMgcHJvdmlkZWQgd2l0aGluIGVhY2ggYmFyKQ0KYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMH0NCiMgQ2FsY3VsYXRlIGNvdW50IGZvciBlYWNoIGFzc2F5IGluIHNvY2lhbCBiZWhhdmlvcg0KdG90YWxfYmVoYXZpb3VyX3NvY2lhbGl0eV9jb3VudCA8LSBiZCAlPiUgDQogIHNlcGFyYXRlX3Jvd3MoYmVoYXZpb3VyX3NvY2lhbGl0eSwgc2VwID0gIixcXHMqIikgJT4lICANCiAgY291bnQoYmVoYXZpb3VyX3NvY2lhbGl0eSkgJT4lIA0KICBuYS5vbWl0KCkNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0KYmVoYXZfc29jaWFsaXR5X3BjdCA8LSB0b3RhbF9iZWhhdmlvdXJfc29jaWFsaXR5X2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4vc3VtKHRvdGFsX2JlaGF2aW91cl9zb2NpYWxpdHlfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbioxMDApDQoNCiMgQ3JlYXRlIGEgYmFyIGNoYXJ0IHdpdGggdGhlIGNvdW50IG9uIHRoZSB4LWF4aXMgYW5kIHNvY2lhbCBiZWhhdmlvdXIgYXNzYXkgb24gdGhlIHktYXhpcw0KZmlnczEwIDwtICBnZ3Bsb3QoYmVoYXZfc29jaWFsaXR5X3BjdCwgYWVzKHggPSByZW9yZGVyKGJlaGF2aW91cl9zb2NpYWxpdHksIG4pLCB5ID0gcGVyY2VudGFnZSkpICsNCiAgDQogICMgQ3VzdG9taXplIHRoZSBhcHBlYXJhbmNlIG9mIHRoZSBiYXJzIA0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICIjNUY4NUFFIiwgY29sb3IgPSAid2hpdGUiLCBhbHBoYSA9IDAuOCwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpKSArDQogIA0KICMgQWRkIGxhYmVscyB0byB0aGUgYmFycyBmb3IgcGVyY2VudGFnZSANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChyb3VuZChwZXJjZW50YWdlLCAxKSwgIiUiKSksIGhqdXN0ID0gLTAuMiwgdmp1c3QgPSAwLjUsIHNpemUgPSA3LCBmb250ZmFjZSA9ICJib2xkIiwgICAgIGNvbG9yID0gImJsYWNrIikgKw0KICAgIA0KICAjIEFkZCBsYWJlbHMgdG8gdGhlIGJhcnMgZm9yIGFic29sdXRlIGNvdW50ICANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwgY29sb3IgPSAid2hpdGUiLCBzaXplID0gNywgaGp1c3QgPSAwLjUsIGZvbnRmYWNlID0gICAiYm9sZCIpICsNCiAgDQogICMgQWRkIGF4aXMgYW5kIHBsb3QgbGFiZWxzDQogIGxhYnMoeCA9ICJTb2NpYWwgQmVoYXZpb3IgQXNzYXkgIiwgeSA9ICJQZXJjZW50YWdlIikgKw0KICANCiAgIyBDdXN0b21pemUgdGhlIHBsb3QgdGhlbWUNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgaGp1c3QgPSAxKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArDQogICAgY29vcmRfZmxpcCgpICsNCiAgICB5bGltKDAsIDEwMCkgKw0KICAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBjKCJBZmZpbGlhdGlvbiB3aXRoIGNvbnNwZWNpZmljXG5tb2RlbCBvciB2aWRlbyIsICJBZmZpbGlhdGlvbiB3aXRoIGEgbGl2ZSBjb25zcGVjaWZpY1xuYmVoaW5kIGEgYmFycmllciIsICJBZmZpbGlhdGlvbiB3aXRoIGNvbnNwZWNpZmljIHdoZXJlXG4gdGhleSBhcmUgZnJlZSB0byBpbnRlcmFjdCIpKQ0KDQpmaWdzMTANCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMTBfYmVoYXZpb3VyX3NvY2lhbGl0eS5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQogZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczEwX2JlaGF2aW91cl9zb2NpYWxpdHkuanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQpgYGANCg0KIyMgRmlndXJlIHMxMSANCkJhciBjaGFydHMgc2hvd2luZyB0aGUgcGVyY2VudGFnZSBhbmQgY291bnRzIG9mIGluY2x1ZGVkIHN0dWRpZXMgYWNjb3JkaW5nIHRvIGV2YWx1YXRlZCBiZWhhdmlvdXJzIHRoYXQgd2VyZSB1bmRlciB0aGUgZm9yYWdpbmcgY2F0ZWdvcnkgKHJhdyBjb3VudCBpcyBwcm92aWRlZCB3aXRoaW4gZWFjaCBiYXIpIA0KYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMH0NCiMgQ2FsY3VsYXRlIGNvdW50IGZvciBlYWNoIGFzc2F5IGluIGZvcmFnaW5nIGJlaGF2aW9yDQp0b3RhbF9iZWhhdmlvdXJfZm9yYWdpbmdfY291bnQgPC0gYmQgJT4lIA0KICBzZXBhcmF0ZV9yb3dzKGJlaGF2aW91cl9mb3JhZ2luZywgc2VwID0gIixcXHMqIikgJT4lICANCiAgY291bnQoYmVoYXZpb3VyX2ZvcmFnaW5nKSAlPiUgDQogIG5hLm9taXQoKQ0KDQojIENhbGN1bGF0ZSBwcm9wb3J0aW9uIGFuZCBwZXJjZW50YWdlIGZvciBlYWNoIGNhdGVnb3J5DQpiZWhhdl9mb3JhZ2luZ19wY3QgPC0gdG90YWxfYmVoYXZpb3VyX2ZvcmFnaW5nX2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4vc3VtKHRvdGFsX2JlaGF2aW91cl9mb3JhZ2luZ19jb3VudCRuKSwNCiAgICAgICAgIHBlcmNlbnRhZ2UgPSBwcm9wb3J0aW9uKjEwMCkNCg0KIyBDcmVhdGUgYSBiYXIgY2hhcnQgd2l0aCB0aGUgY291bnQgb24gdGhlIHgtYXhpcyBhbmQgZm9yYWdpbmcgYmVoYXZpb3VyIGFzc2F5IG9uIHRoZSB5LWF4aXMNCmZpZ3MxMSA8LSAgZ2dwbG90KGJlaGF2X2ZvcmFnaW5nX3BjdCwgYWVzKHggPSByZW9yZGVyKGJlaGF2aW91cl9mb3JhZ2luZywgbiksIHkgPSBwZXJjZW50YWdlKSkgKw0KICANCiAgIyBDdXN0b21pemUgdGhlIGFwcGVhcmFuY2Ugb2YgdGhlIGJhcnMgDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gIiM1Rjg1QUUiLCBjb2xvciA9ICJ3aGl0ZSIsIGFscGhhID0gMC44LCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSkpICsNCiAgDQogIyBBZGQgbGFiZWxzIHRvIHRoZSBiYXJzIGZvciBwZXJjZW50YWdlIA0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUwKHJvdW5kKHBlcmNlbnRhZ2UsIDEpLCAiJSIpKSwgaGp1c3QgPSAtMC4yLCB2anVzdCA9IDAuNSwgc2l6ZSA9IDcsIGZvbnRmYWNlID0gImJvbGQiLCAgICAgY29sb3IgPSAiYmxhY2siKSArDQogICAgDQogICMgQWRkIGxhYmVscyB0byB0aGUgYmFycyBmb3IgYWJzb2x1dGUgY291bnQgIA0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCBjb2xvciA9ICJ3aGl0ZSIsIHNpemUgPSA3LCBoanVzdCA9IDAuNSwgZm9udGZhY2UgPSAgICJib2xkIikgKw0KICANCiAgIyBBZGQgYXhpcyBhbmQgcGxvdCBsYWJlbHMNCiAgbGFicyh4ID0gIkZvcmFnaW5nIEJlaGF2aW9yIEFzc2F5IiwgeSA9ICJQZXJjZW50YWdlIikgKw0KICANCiAgIyBDdXN0b21pemUgdGhlIHBsb3QgdGhlbWUNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgaGp1c3QgPSAxKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArDQogICAgY29vcmRfZmxpcCgpICsNCiAgICB5bGltKDAsIDEwMCkgKw0KICAgIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gYygiTG9jb21vdG9yIEFjdGl2aXR5XG4gd2l0aGluIHRoaXMgY29udGV4dCIsICJPbGZhY3Ryb3lcbnByZWZlcmVuY2UgdGVzdCIsICJGb3JhZ2luZyBvbiBhIGxpdmVcbmZvb2Qgc291cmNlIiwgIkZvcmFnaW5nIG9uIGEgbm90XG4gbGl2ZSBmb29kIHNvdXJjZSIpKQ0KDQoNCmZpZ3MxMQ0KIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MxMV9iZWhhdmlvdXJfZm9yYWdpbmcucGRmIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MxMV9iZWhhdmlvdXJfZm9yYWdpbmcuanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQoNCmBgYA0KDQojIyBGaWd1cmUgczEyIA0KQmFyIGNoYXJ0cyBzaG93aW5nIHRoZSBwZXJjZW50YWdlIGFuZCBjb3VudHMgb2YgaW5jbHVkZWQgc3R1ZGllcyBhY2NvcmRpbmcgdG8gZXZhbHVhdGVkIGJlaGF2aW91cnMgdGhhdCB3ZXJlIHVuZGVyIHRoZSBhbnRpcHJlZGF0b3IgY2F0ZWdvcnkgKHJhdyBjb3VudCBpcyBwcm92aWRlZCB3aXRoaW4gZWFjaCBiYXIpIA0KYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMH0NCiMgQ2FsY3VsYXRlIGNvdW50IGZvciBlYWNoIGFzc2F5IGluIGFudGlwcmVkYXRvciBiZWhhdmlvcg0KdG90YWxfYmVoYXZpb3VyX2FudGlwcmVkYXRvcl9jb3VudCA8LSBiZCAlPiUgDQogIHNlcGFyYXRlX3Jvd3MoYmVoYXZpb3VyX2FudGlwcmVkYXRvciwgc2VwID0gIixcXHMqIikgJT4lICANCiAgY291bnQoYmVoYXZpb3VyX2FudGlwcmVkYXRvcikgJT4lIA0KICBuYS5vbWl0KCkNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0KYmVoYXZfYW50aXByZWRhdG9yX3BjdCA8LSB0b3RhbF9iZWhhdmlvdXJfYW50aXByZWRhdG9yX2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4vc3VtKHRvdGFsX2JlaGF2aW91cl9hbnRpcHJlZGF0b3JfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbioxMDApDQoNCiMgQ3JlYXRlIGEgYmFyIGNoYXJ0IHdpdGggdGhlIGNvdW50IG9uIHRoZSB4LWF4aXMgYW5kIGFudGlwcmVkYXRvciBiZWhhdmlvdXIgYXNzYXkgb24gdGhlIHktYXhpcw0KZmlnczEyIDwtIGdncGxvdChiZWhhdl9hbnRpcHJlZGF0b3JfcGN0LCBhZXMoeCA9IHJlb3JkZXIoYmVoYXZpb3VyX2FudGlwcmVkYXRvciwgbiksIHkgPSBwZXJjZW50YWdlKSkgKw0KICANCiAgIyBDdXN0b21pemUgdGhlIGFwcGVhcmFuY2Ugb2YgdGhlIGJhcnMgDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gIiM1Rjg1QUUiLCBjb2xvciA9ICJ3aGl0ZSIsIGFscGhhID0gMC44LCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSkpICsNCiAgDQogICMgQWRkIGxhYmVscyB0byB0aGUgYmFycyBmb3IgcGVyY2VudGFnZSANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChyb3VuZChwZXJjZW50YWdlLCAxKSwgIiUiKSksIGhqdXN0ID0gLTAuMiwgdmp1c3QgPSAwLjUsIHNpemUgPSA3LCBmb250ZmFjZSA9ICJib2xkIiwgY29sb3IgPSAiYmxhY2siKSArDQogICAgDQogICMgQWRkIGxhYmVscyB0byB0aGUgYmFycyBmb3IgYWJzb2x1dGUgY291bnQgIA0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCBjb2xvciA9ICJ3aGl0ZSIsIHNpemUgPSA3LCBoanVzdCA9IDAuNSwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgDQogICMgQWRkIGF4aXMgYW5kIHBsb3QgbGFiZWxzDQogIGxhYnMoeCA9ICJBbnRpcHJlZGF0b3IgQmVoYXZpb3IgQXNzYXkiLCB5ID0gIlBlcmNlbnRhZ2UiKSArDQogIA0KICAjIEN1c3RvbWl6ZSB0aGUgcGxvdCB0aGVtZQ0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgaGp1c3QgPSAxKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArDQogICAgICAgIGNvb3JkX2ZsaXAoKSArDQogICAgICAgIHlsaW0oMCwgMTAwKSArDQogICAgICAgIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gYygiTG9jb21vdG9yIEFjdGl2aXR5XG4gd2l0aGluIHRoaXMgY29udGV4dCIsICJSZXNwb25zZSB0byBhIGxpdmUgcHJlZGF0b3JcbmJlaGluZCBhIGJhcnJpZXIiLCAiUmVzcG9uc2UgdG8gYSBzaW11bGF0ZWRcbiBwcmVkYXRvciIpKQ0KDQpmaWdzMTINCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMTJfYmVoYXZpb3VyX2FudGlwcmVkYXRvci5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQogZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczEyX2JlaGF2aW91cl9hbnRpcHJlZGF0b3IuanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQpgYGANCg0KIyMgRmlndXJlIHMxMyANCkJhciBjaGFydHMgc2hvd2luZyB0aGUgcGVyY2VudGFnZSBhbmQgY291bnRzIG9mIGluY2x1ZGVkIHN0dWRpZXMgYWNjb3JkaW5nIHRvIGV2YWx1YXRlZCBiZWhhdmlvdXJzIHRoYXQgd2VyZSB1bmRlciB0aGUgYW54aWV0eS9ib2xkbmVzcyBjYXRlZ29yeSAocmF3IGNvdW50IGlzIHByb3ZpZGVkIHdpdGhpbiBlYWNoIGJhcikNCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTB9DQojIENhbGN1bGF0ZSBjb3VudCBmb3IgZWFjaCBhc3NheSBpbiBhbnhpZXR5IGJlaGF2aW9yDQp0b3RhbF9iZWhhdmlvdXJfYW54aWV0eV9jb3VudCA8LSBiZCAlPiUgDQogIHNlcGFyYXRlX3Jvd3MoYmVoYXZpb3VyX2FueGlldHksIHNlcCA9ICIsXFxzKiIpICU+JSAgDQogIGNvdW50KGJlaGF2aW91cl9hbnhpZXR5KSAlPiUgDQogIG5hLm9taXQoKQ0KDQojIENhbGN1bGF0ZSBwcm9wb3J0aW9uIGFuZCBwZXJjZW50YWdlIGZvciBlYWNoIGNhdGVnb3J5DQpiZWhhdl9hbnhpZXR5X3BjdCA8LSB0b3RhbF9iZWhhdmlvdXJfYW54aWV0eV9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuL3N1bSh0b3RhbF9iZWhhdmlvdXJfYW54aWV0eV9jb3VudCRuKSwNCiAgICAgICAgIHBlcmNlbnRhZ2UgPSBwcm9wb3J0aW9uKjEwMCkNCg0KIyBDcmVhdGUgYSBiYXIgY2hhcnQgd2l0aCB0aGUgY291bnQgb24gdGhlIHgtYXhpcyBhbmQgYW54aWV0eSBiZWhhdmlvciBhc3NheSBvbiB0aGUgeS1heGlzDQpmaWdzMTMgPC0gZ2dwbG90KGJlaGF2X2FueGlldHlfcGN0LCBhZXMoeCA9IHJlb3JkZXIoYmVoYXZpb3VyX2FueGlldHksIG4pLCB5ID0gcGVyY2VudGFnZSkpICsNCiAgDQogICMgQ3VzdG9taXplIHRoZSBhcHBlYXJhbmNlIG9mIHRoZSBiYXJzIA0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICIjNUY4NUFFIiwgY29sb3IgPSAid2hpdGUiLCBhbHBoYSA9IDAuOCwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpKSArDQogIA0KICAjIEFkZCBsYWJlbHMgdG8gdGhlIGJhcnMgZm9yIHBlcmNlbnRhZ2UgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZTAocm91bmQocGVyY2VudGFnZSwgMSksICIlIikpLCBoanVzdCA9IC0wLjIsIHZqdXN0ID0gMC41LCBzaXplID0gNywgZm9udGZhY2UgPSAiYm9sZCIsIGNvbG9yID0gImJsYWNrIikgKw0KICAgIA0KICAjIEFkZCBsYWJlbHMgdG8gdGhlIGJhcnMgZm9yIGFic29sdXRlIGNvdW50ICANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwgY29sb3IgPSAid2hpdGUiLCBzaXplID0gNywgaGp1c3QgPSAwLjUsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIA0KICAjIEFkZCBheGlzIGFuZCBwbG90IGxhYmVscw0KICBsYWJzKHggPSAiQW54aWV0eSBCZWhhdmlvciBBc3NheSIsIHkgPSAiUGVyY2VudGFnZSIpICsNCiAgDQogICMgQ3VzdG9taXplIHRoZSBwbG90IHRoZW1lDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwLCBoanVzdCA9IDEpLA0KICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgICAgICAgY29vcmRfZmxpcCgpICsNCiAgICAgICAgeWxpbSgwLCA4MCkgKyANCiAgICAgICAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBjKCJMaWdodHMgb24tb2ZmIiwgIlNob2FsaW5nIiwgIkxvY29tb3RvciBBY3Rpdml0eVxuIHdpdGhpbiB0aGlzIGNvbnRleHQiLCAiSGFiaXR1YXRpb24gdGFzayIsICJCbGFjay13aGl0ZSBhcmVhIiwgIk5vdmVsIHRhbmsgb3JcbiBleHBsb3JhdGlvbiIpKQ0KDQoNCmZpZ3MxMw0KICBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMTNfYmVoYXZpb3VyX2FueGlldHkucGRmIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KICBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMTNfYmVoYXZpb3VyX2FueGlldHkuanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQoNCmBgYA0KDQoNCiMjIEZpZ3VyZSBzMTQgDQpIZWF0IG1hcCBwbG90IHNob3dpbmcgY291bnRzIG9mIGluY2x1ZGVkIHBhcGVycyBhY2NvcmRpbmcgdG8gY29tYmluYXRpb25zIG9mIGV2YWx1YXRlZCBiZWhhdmlvdXJzIGFuZCBwZXN0aWNpZGUgdGFyZ2V0IGNsYXNzDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBKb2luIHRoZSBiZWhhdmlvdXIgZGV0YWlscyBhbmQgcGVzdGljaWRlIGRldGFpbHMgYnkgInN0dWR5X2lkIg0KYmRfcGQgPC0gbGVmdF9qb2luKGJkLCBwZCwgYnkgPSAic3R1ZHlfaWQiKQ0KDQojIFNlcGFyYXRlIHJvd3MgaW4gImJkX3BkIiBieSAiYmVoYXZpb3VyYWxfY2xhc3MiIGFuZCAicGVzdGljaWRlX3RhcmdldF9jbGFzcyIgY29sdW1ucw0KYmRfcGQxIDwtIHNlcGFyYXRlX3Jvd3MoYmRfcGQsIGJlaGF2aW91cmFsX2NsYXNzLCBzZXAgPSAiLFxccyoiLCBjb252ZXJ0ID0gVFJVRSkNCmJkX3BkMTwtIHNlcGFyYXRlX3Jvd3MoYmRfcGQxLCBwZXN0aWNpZGVfdGFyZ2V0X2NsYXNzLCBzZXAgPSAiLFxccyoiLCBjb252ZXJ0ID0gVFJVRSkNCg0KIyBHcm91cCBieSAiYmVoYXZpb3VyYWxfY2xhc3MiIGFuZCAicGVzdGljaWRlX3RhcmdldF9jbGFzcyIgYW5kIHN1bW1hcml6ZSBjb3VudA0KYmRfcGRfc3VtbWFyeTEgPC0gYmRfcGQxICU+JQ0KICBtdXRhdGUoYmVoYXZpb3VyYWxfY2xhc3MgPSBzdHJfdHJpbShiZWhhdmlvdXJhbF9jbGFzcyksDQogICAgICAgICBwZXN0aWNpZGVfdGFyZ2V0X2NsYXNzID0gc3RyX3RyaW0ocGVzdGljaWRlX3RhcmdldF9jbGFzcykpICU+JQ0KICBncm91cF9ieShiZWhhdmlvdXJhbF9jbGFzcywgcGVzdGljaWRlX3RhcmdldF9jbGFzcykgJT4lDQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lDQogIHVuZ3JvdXAoKSANCg0KIyBDcmVhdGUgYSBoZWF0bWFwIHdpdGggcGVzdGljaWRlIHRhcmdldCBjbGFzcyBvbiB0aGUgeC1heGlzIGFuZCBiZWhhdmlvdXJhbCBjbGFzcyBvbiB0aGUgeS1heGlzDQpmaWdzMTQgPC0gZ2dwbG90KGJkX3BkX3N1bW1hcnkxLCBhZXMoeCA9IHBlc3RpY2lkZV90YXJnZXRfY2xhc3MsIHkgPSBiZWhhdmlvdXJhbF9jbGFzcywgZmlsbCA9IGNvdW50KSkgKw0KICANCiAgI0NyZWF0ZSBhbmQgZmlsbCBlYWNoIHRpbGUgDQogIGdlb21fdGlsZShjb2xvciA9ICJ3aGl0ZSIpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiI0YwRjRGOCIsIGhpZ2ggPSAiIzQ0NjQ4NyIpICsNCiAgDQogICMgQWRkIGxhYmVscyB0byB0aGUgYmFycyBmb3IgYWJzb2x1dGUgY291bnQgIA0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY291bnQpLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSA3KSArIA0KICANCiAgIyBBZGQgYXhpcyBhbmQgcGxvdCBsYWJlbHMNCiAgbGFicyh4ID0gIlBlc3RpY2lkZSBUYXJnZXQgQ2xhc3MiLCB5ID0gIkJlaGF2aW91cmFsIENsYXNzIiwgZmlsbCA9ICJDb3VudCIpICsNCiAgDQogICMgQ3VzdG9taXplIHRoZSBwbG90IHRoZW1lDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwLCBoanVzdCA9IDEpLA0KICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9IDIwKSwNCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCkpDQoNCg0KZmlnczE0DQogZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczE0X2JlaGF2aW91cl90YXJnZXRfY2xhc3NfaGVhdF9tYXAucGRmIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MxNF9iZWhhdmlvdXJfdGFyZ2V0X2NsYXNzX2hlYXRfbWFwLmpwZyIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCg0KYGBgDQoNCiMjIEZpZ3VyZSBzMTUgDQpIZWF0IG1hcCBwbG90IHNob3dpbmcgY291bnRzIG9mIGluY2x1ZGVkIHBhcGVycyBhY2NvcmRpbmcgdG8gY29tYmluYXRpb25zIG9mIGV2YWx1YXRlZCBiZWhhdmlvdXJzIGFuZCBwZXN0aWNpZGUgY2hlbWljYWwgY2xhc3MgKGZpbHRlcmVkIGZvciB0b3AgNSBtb3N0IGFidW5kYW50IGNoZW1pY2FsIGNsYXNzZXMpDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBTZXBhcmF0ZSByb3dzIGJ5IGJlaGF2aW91cmFsX2NsYXNzIGFuZCBwZXN0aWNpZGVfY2hlbWljYWxfY2xhc3MgY29sdW1ucw0KYmRfcGQyIDwtIHNlcGFyYXRlX3Jvd3MoYmRfcGQsIGJlaGF2aW91cmFsX2NsYXNzLCBzZXAgPSAiLFxccyoiLCBjb252ZXJ0ID0gVFJVRSkNCmJkX3BkMiA8LSBzZXBhcmF0ZV9yb3dzKGJkX3BkMiwgcGVzdGljaWRlX2NoZW1pY2FsX2NsYXNzLCBzZXAgPSAiLCIsIGNvbnZlcnQgPSBUUlVFKQ0KDQojIEdldCB0aGUgdG9wIDMgbW9zdCBudW1lcm91cyBwZXN0aWNpZGUgY2hlbWljYWwgY2xhc3Nlcw0KYmRfcGRfc3VtbWFyeTIgPC0gYmRfcGQyICU+JQ0KICBtdXRhdGUoYmVoYXZpb3VyYWxfY2xhc3MgPSBzdHJfdHJpbShiZWhhdmlvdXJhbF9jbGFzcyksDQogICAgICAgICBwZXN0aWNpZGVfdGFyZ2V0X2NsYXNzID0gc3RyX3RyaW0ocGVzdGljaWRlX2NoZW1pY2FsX2NsYXNzKSkgJT4lDQogIGdyb3VwX2J5KGJlaGF2aW91cmFsX2NsYXNzLCBwZXN0aWNpZGVfY2hlbWljYWxfY2xhc3MpICU+JQ0KICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JQ0KICB1bmdyb3VwKCkgDQoNCnRvcF9wZXN0aWNpZGVfY2xhc3NlcyA8LSBiZF9wZF9zdW1tYXJ5MiAlPiUNCiAgZmlsdGVyKCFpcy5uYShwZXN0aWNpZGVfY2hlbWljYWxfY2xhc3MpKSAlPiUNCiAgZ3JvdXBfYnkocGVzdGljaWRlX2NoZW1pY2FsX2NsYXNzKSAlPiUNCiAgc3VtbWFyaXNlKGNvdW50ID0gc3VtKGNvdW50KSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgdG9wX24oNSwgY291bnQpICU+JSANCiAgcHVsbChwZXN0aWNpZGVfY2hlbWljYWxfY2xhc3MpDQoNCiMgU3Vic2V0IHRoZSBkYXRhIHRvIGluY2x1ZGUgb25seSB0aGUgdG9wIDMgY2xhc3Nlcw0KYmRfcGRfc3VtbWFyeV90b3A1IDwtIGJkX3BkX3N1bW1hcnkyICU+JQ0KICBmaWx0ZXIocGVzdGljaWRlX2NoZW1pY2FsX2NsYXNzICVpbiUgdG9wX3Blc3RpY2lkZV9jbGFzc2VzKQ0KDQojIENyZWF0ZSBhIGhlYXRtYXAgd2l0aCBwZXN0aWNpZGUgY2hlbWljYWwgY2xhc3Mgb24gdGhlIHgtYXhpcyBhbmQgYmVoYXZpb3JhbCBjbGFzcyBvbiB0aGUgeS1heGlzDQpmaWdzMTUgPC0gZ2dwbG90KGJkX3BkX3N1bW1hcnlfdG9wNSwgYWVzKHggPSBwZXN0aWNpZGVfY2hlbWljYWxfY2xhc3MsIHkgPSBiZWhhdmlvdXJhbF9jbGFzcywgZmlsbCA9IGNvdW50KSkgKw0KICANCiAgI0NyZWF0ZSBhbmQgZmlsbCBlYWNoIHRpbGUgDQogIGdlb21fdGlsZShjb2xvciA9ICJ3aGl0ZSIpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiI0YwRjRGOCIsIGhpZ2ggPSAiIzQ0NjQ4NyIpICsNCiAgDQogICMgQWRkIGxhYmVscyB0byB0aGUgYmFycyBmb3IgYWJzb2x1dGUgY291bnQgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBpZmVsc2UoY291bnQgPiAwLCBjb3VudCwgIiIpKSwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gNykgKyAgDQogIA0KICAjIEFkZCBheGlzIGFuZCBwbG90IGxhYmVscw0KICBsYWJzKHggPSAiUGVzdGljaWRlIENoZW1pY2FsIENsYXNzIiwgeSA9ICJCZWhhdmlvdXJhbCBDbGFzcyIsIGZpbGwgPSAiQ291bnQiKSArDQogIA0KICAjIEN1c3RvbWl6ZSB0aGUgcGxvdCB0aGVtZQ0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgaGp1c3QgPSAxKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPSAyMCksDQogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApKQ0KDQpmaWdzMTUNCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMTVfYmVoYXZpb3VyX2NoZW1pY2FsX2NsYXNzX2hlYXRfbWFwLnBkZiIpLCB3aWR0aCA9IDIxLCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMTVfYmVoYXZpb3VyX2NoZW1pY2FsX2NsYXNzX2hlYXRfbWFwLmpwZyIpLCB3aWR0aCA9IDIxLCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCg0KDQpgYGANCg0KIyMgRmlndXJlIHMxNiANCkhlYXQgbWFwIHBsb3Qgc2hvd2luZyBjb3VudHMgb2YgaW5jbHVkZWQgcGFwZXJzIGFjY29yZGluZyB0byBjb21iaW5hdGlvbnMgb2YgZXZhbHVhdGVkIGxpZmUgc3RhZ2VzIGFuZCBwZXN0aWNpZGUgY2hlbWljYWwgY2xhc3MgKGZpbHRlcmVkIGZvciB0b3AgNSBtb3N0IGFidW5kYW50IGNoZW1pY2FsIGNsYXNzZXMpDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KDQojIEpvaW4gdGhlIHN0eWR0IGRldGFpbHMgd2l0aCBwZXN0aWNpZGUgZGV0YWlscyBieSAic3R1ZHlfaWQiLiANCnNkX3BkIDwtIGxlZnRfam9pbihzZCwgcGQsIGJ5ID0gInN0dWR5X2lkIikNCg0KIyBTZXBhcmF0ZSByb3dzIGluICJzZF9wZCIgYnkgImxpZmVfc3RhZ2VfZXhwb3N1cmUiIGFuZCAicGVzdGljaWRlX2NoZW1pY2FsX2NsYXNzIiBjb2x1bW5zDQpzZF9wZDEgPC0gc2VwYXJhdGVfcm93cyhzZF9wZCwgbGlmZV9zdGFnZV9leHBvc3VyZSwgc2VwID0gIiwiLCBjb252ZXJ0ID0gVFJVRSkNCnNkX3BkMSA8LSBzZXBhcmF0ZV9yb3dzKHNkX3BkMSwgcGVzdGljaWRlX2NoZW1pY2FsX2NsYXNzLCBzZXAgPSAiLCIsIGNvbnZlcnQgPSBUUlVFKQ0KDQojIEdyb3VwIGJ5ICJsaWZlX3N0YWdlX2V4cG9zdXJlIiBhbmQgInBlc3RpY2lkZV9jaGVtaWNhbF9jbGFzcyIgYW5kIHN1bW1hcml6ZSBjb3VudA0Kc2RfcGRfc3VtbWFyeTEgPC0gc2RfcGQxICU+JQ0KICBtdXRhdGUobGlmZV9zdGFnZV9leHBvc3VyZSA9IHN0cl90cmltKGxpZmVfc3RhZ2VfZXhwb3N1cmUpLA0KICAgICAgICAgcGVzdGljaWRlX2NoZW1pY2FsX2NsYXNzID0gc3RyX3RyaW0ocGVzdGljaWRlX2NoZW1pY2FsX2NsYXNzKSkgJT4lDQogIGdyb3VwX2J5KGxpZmVfc3RhZ2VfZXhwb3N1cmUsIHBlc3RpY2lkZV9jaGVtaWNhbF9jbGFzcykgJT4lDQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lDQogIHVuZ3JvdXAoKQ0KDQp0b3BfcGVzdGljaWRlX2NsYXNzZXMgPC0gc2RfcGRfc3VtbWFyeTEgJT4lDQogIGZpbHRlcighaXMubmEocGVzdGljaWRlX2NoZW1pY2FsX2NsYXNzKSkgJT4lDQogIGdyb3VwX2J5KHBlc3RpY2lkZV9jaGVtaWNhbF9jbGFzcykgJT4lDQogIHN1bW1hcmlzZShjb3VudCA9IHN1bShjb3VudCkpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIHRvcF9uKDQsIGNvdW50KSAlPiUNCiAgcHVsbChwZXN0aWNpZGVfY2hlbWljYWxfY2xhc3MpDQoNCnNkX3BkX3N1bW1hcnkxX3RvcDUgPC0gc2RfcGRfc3VtbWFyeTEgJT4lDQogIGZpbHRlcihwZXN0aWNpZGVfY2hlbWljYWxfY2xhc3MgJWluJSB0b3BfcGVzdGljaWRlX2NsYXNzZXMpDQoNCiMgQ3JlYXRlIGEgaGVhdG1hcCB3aXRoIHBlc3RpY2lkZSB0YXJnZXQgY2xhc3Mgb24gdGhlIHgtYXhpcyBhbmQgYmVoYXZpb3VyYWwgY2xhc3Mgb24gdGhlIHktYXhpcw0KZmlnczE2IDwtIGdncGxvdChzZF9wZF9zdW1tYXJ5MV90b3A1LCBhZXMoeCA9IHBlc3RpY2lkZV9jaGVtaWNhbF9jbGFzcywgeSA9IGxpZmVfc3RhZ2VfZXhwb3N1cmUsIGZpbGwgPSBjb3VudCkpICsNCiAgDQogICNDcmVhdGUgYW5kIGZpbGwgZWFjaCB0aWxlDQogIGdlb21fdGlsZShjb2xvciA9ICJ3aGl0ZSIpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiI0YwRjRGOCIsIGhpZ2ggPSAiIzQ0NjQ4NyIpICsNCiAgDQogICMgQWRkIGxhYmVscyB0byB0aGUgYmFycyBmb3IgYWJzb2x1dGUgY291bnQgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBpZmVsc2UoY291bnQgPiAwLCBjb3VudCwgIiIpKSwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gNykgKw0KICANCiAgIyBBZGQgYXhpcyBhbmQgcGxvdCBsYWJlbHMNCiAgbGFicyh4ID0gIlBlc3RpY2lkZSBDaGVtaWNhbCBDbGFzcyIsIHkgPSAiTGlmZSBTdGFnZSBFeHBvc3VyZSIsIGZpbGwgPSAiQ291bnQiKSArDQogIA0KICAjIEN1c3RvbWl6ZSB0aGUgcGxvdCB0aGVtZQ0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgaGp1c3QgPSAxKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPSAyMCksDQogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApKQ0KDQpmaWdzMTYNCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMTZfbGlmZV9zdGFnZV9jaGVtaWNhbF9jbGFzc19oZWF0X21hcC5wZGYiKSwgd2lkdGggPSAyMSwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQogZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczE2X2xpZmVfc3RhZ2VfY2hlbWljYWxfY2xhc3NfaGVhdF9tYXAuanBnIiksIHdpZHRoID0gMjEsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQpgYGANCg0KIyMgRmlndXJlIHMxNyANCkhlYXQgbWFwIHBsb3Qgc2hvd2luZyBjb3VudHMgb2YgaW5jbHVkZWQgcGFwZXJzIGFjY29yZGluZyB0byBjb21iaW5hdGlvbnMgb2YgZXZhbHVhdGVkIGxpZmUgc3RhZ2VzIGFuZCBwZXN0aWNpZGUgdGFyZ2V0IGNsYXNzDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KDQojIFNlcGFyYXRlIHJvd3MgYnkgbGlmZV9zdGFnZV9leHBvc3VyZSBhbmQgcGVzdGljaWRlX3RhcmdldF9jbGFzcyBjb2x1bW5zDQpzZF9wZDIgPC0gc2VwYXJhdGVfcm93cyhzZF9wZCwgbGlmZV9zdGFnZV9leHBvc3VyZSwgc2VwID0gIiwiLCBjb252ZXJ0ID0gVFJVRSkNCnNkX3BkMiA8LSBzZXBhcmF0ZV9yb3dzKHNkX3BkMiwgcGVzdGljaWRlX3RhcmdldF9jbGFzcywgc2VwID0gIiwiLCBjb252ZXJ0ID0gVFJVRSkNCg0KIyBHcm91cCBieSAibGlmZV9zdGFnZV9leHBvc3VyZSIgYW5kICJwZXN0aWNpZGVfdGFyZ2V0X2NsYXNzIiBhbmQgc3VtbWFyaXplIGNvdW50DQpzZF9wZF9zdW1tYXJ5MiA8LSBzZF9wZDIgJT4lDQogIG11dGF0ZShsaWZlX3N0YWdlX2V4cG9zdXJlID0gc3RyX3RyaW0obGlmZV9zdGFnZV9leHBvc3VyZSksDQogICAgICAgICBwZXN0aWNpZGVfdGFyZ2V0X2NsYXNzID0gc3RyX3RyaW0ocGVzdGljaWRlX3RhcmdldF9jbGFzcykpICU+JQ0KICBncm91cF9ieShsaWZlX3N0YWdlX2V4cG9zdXJlLCBwZXN0aWNpZGVfdGFyZ2V0X2NsYXNzKSAlPiUNCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUNCiAgdW5ncm91cCgpDQoNCiMgQ3JlYXRlIGEgaGVhdG1hcCB3aXRoIHBlc3RpY2lkZSB0YXJnZXQgY2xhc3Mgb24gdGhlIHgtYXhpcyBhbmQgbGlmZSBzdGFnZSBleHBvc3VyZSBvbiB0aGUgeS1heGlzDQpmaWdzMTcgPC0gZ2dwbG90KHNkX3BkX3N1bW1hcnkyLCBhZXMoeCA9IHBlc3RpY2lkZV90YXJnZXRfY2xhc3MsIHkgPSBsaWZlX3N0YWdlX2V4cG9zdXJlLCBmaWxsID0gY291bnQpKSArDQogIA0KICAjQ3JlYXRlIGFuZCBmaWxsIGVhY2ggdGlsZQ0KICBnZW9tX3RpbGUoY29sb3IgPSAid2hpdGUiKSArDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gIiNGMEY0RjgiLCBoaWdoID0gIiM0NDY0ODciKSArDQogIA0KICAjIEFkZCBsYWJlbHMgdG8gdGhlIGJhcnMgZm9yIGFic29sdXRlIGNvdW50IA0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gaWZlbHNlKGNvdW50ID4gMCwgY291bnQsICIiKSksIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDcpICsNCiAgDQogICMgQWRkIGF4aXMgYW5kIHBsb3QgbGFiZWxzDQogIGxhYnMoeCA9ICJQZXN0aWNpZGUgVGFyZ2V0IENsYXNzIiwgeSA9ICJMaWZlIFN0YWdlIEV4cG9zdXJlIiwgZmlsbCA9ICJDb3VudCIpICsNCiAgDQogICMgQ3VzdG9taXplIHRoZSBwbG90IHRoZW1lDQogdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjAsIGhqdXN0ID0gMSksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0gMjApLA0KICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSkNCg0KDQpmaWdzMTcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczE3X2xpZmVfc3RhZ2VfdGFyZ2V0X2NsYXNzX2hlYXRfbWFwLnBkZiIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMTdfbGlmZV9zdGFnZV90YXJnZXRfY2xhc3NfaGVhdF9tYXAuanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQpgYGANCg0KDQojIE9iamVjdGl2ZSA0DQpUbyBleGFtaW5lIGhvdyBhcmUgYXV0aG9ycyBjb25uZWN0ZWQgYmV0d2VlbiBjb3VudHJpZXMgYW5kIGhvdyBpcyB0aGUgbGl0ZXJhdHVyZSBjb25uZWN0ZWQgYmV0d2VlbiBhbmQgd2l0aGluIGRpc2NpcGxpbmVzDQoNCiMjIEZpZ3VyZSBzMjMgDQpBdmVyYWdlIHRvdGFsIGNpdGF0aW9uIGNvdW50IHBlciB5ZWFyIGZvciBwYXBlcnMgaW5jbHVkZWQgaW4gdGhlIHN5c3RlbWF0aWMgbWFwDQojIyBGaWd1cmUgczI0IA0KQXZlcmFnZSBhcnRpY2xlIGNpdGF0aW9uIHBlciB5ZWFyIGZvciBwYXBlcnMgaW5jbHVkZWQgaW4gdGhlIHN5c3RlbWF0aWMgbWFwDQojIyBGaWd1cmUgczI1IA0KQW5udWFsIHNjaWVudGlmaWMgcHJvZHVjdGlvbiBjb3VudHMgb2YgcGFwZXJzIGluY2x1ZGVkIGluIHRoZSBzeXN0ZW1hdGljIG1hcA0KIyMgRmlndXJlIHMyNiANCk1vc3QgcHJvZHVjdGl2ZSBjb3VudHJpZXMgb2YgYXV0aG9yIGFmZmlsaWF0aW9ucyBmb3IgcGFwZXJzIGluY2x1ZGVkIGluIHRoZSBzeXN0ZW1hdGljIG1hcA0KYGBge3IsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTV9DQojIFBlcmZvcm0gYmlibGlvbWV0cmljIGFuYWx5c2lzIG9uIGRhdGFzZXQgImJpYl9zY28iDQpmaWdzMjQgPC0gYmlibGlvQW5hbHlzaXMoYmliX3NjbykNCg0KIyBEaXNwbGF5IHRoZSBwbG90IG9mIHRoZSBhbmFseXNpcyByZXN1bHRzDQpwbG90KGZpZ3MyNCkNCg0KYGBgDQoNCg0KIyMgRmlndXJlIHMyOCANClRoZW1hdGljIG1hcCBiYXNlZCBvbiBrZXl3b3JkcyBleHRyYWN0ZWQgZnJvbSBJRCBmaWVsZCAodGFrZW4gZnJvbSBTY29wdXMgYmlibGlvbWV0cmljIGluZm9ybWF0aW9uKSBvZiBwYXBlcnMgaW5jbHVkZWQgaW4gdGhlIHN5c3RlbWF0aWMgbWFwDQpgYGB7ciwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NX0NCiMgU2V0IHBsb3QgcGFyYW1ldGVycyB0byBkaXNwbGF5IGEgc2luZ2xlIHBsb3Qgd2l0aCBuYXJyb3cgbWFyZ2lucw0KcGFyKG1mcm93PWMoMSwxKSwgbWFyPWMoMCwyLDAsMikpDQoNCiMgR2VuZXJhdGUgYSB0aGVtYXRpYyBtYXAgb2YgdGhlICJiaWJfc2NvIiBkYXRhc2V0LCB1c2luZyB0aGUgIklEIiBmaWVsZCBhcyB0aGUgYmFzaXMgZm9yIHRoZSBtYXANCmZpZ3MyOCA8LSB0aGVtYXRpY01hcChiaWJfc2NvLCBmaWVsZCA9ICJJRCIsIG4gPSAxMDAwLCBtaW5mcmVxID0gNSwgc3RlbW1pbmcgPSBGQUxTRSwgc2l6ZSA9IDAuNSwgbi5sYWJlbHMgPSAxLCByZXBlbCA9IFRSVUUpDQoNCiMgRGlzcGxheSB0aGUgcmVzdWx0aW5nIG1hcCB1c2luZyB0aGUgInBsb3QiIGZ1bmN0aW9uDQpwbG90KGZpZ3MyOCRtYXApDQoNCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMjhfdGhlbWF0aWNfbWFwLnBkZiIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMjhfdGhlbWF0aWNfbWFwLmpwZyIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCg0KYGBgDQoNCiMjIEZpZ3VyZSA3IA0KSGVhdCBtYXAgb2Ygd29ybGQgc2hvd2luZyB0aGUgY291bnRyeS1sZXZlbCBjb3VudHMgZm9yIGZpcnN0IGF1dGhvcnPigJkgY291bnRyeSBvZiBhZmZpbGlhdGlvbiBvZiBzdHVkaWVzIGludmVzdGlnYXRpbmcgdGhlIGltcGFjdHMgb2YgcGVzdGljaWRlIGV4cG9zdXJlIG9uIHplYnJhZmlzaCBiZWhhdmlvdXIuIEdyZXkgaW5kaWNhdGVzIG5vIHB1YmxpY2F0aW9ucyBhZmZpbGlhdGVkIHdpdGggYSBnaXZlbiBjb3VudHJ5IGluIG91ciBkYXRhIHNldC4gDQpgYGB7ciwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NX0NCg0KIyBFeHRyYWN0IGNvdW50cnkgaW5mb3JtYXRpb24gZnJvbSB0aGUgIkFVMV9DTyIgYW5kICJBVV9DTyIgZmllbGRzIG9mIHRoZSAiYmliX3NjbyIgZGF0YXNldA0KYmlibWFwIDwtIG1ldGFUYWdFeHRyYWN0aW9uKGJpYl9zY28sIEZpZWxkID0gIkFVMV9DTyIsIHNlcCA9ICI7IikgDQpiaWJtYXAgPC0gbWV0YVRhZ0V4dHJhY3Rpb24oYmlibWFwLCBGaWVsZCA9ICJBVV9DTyIsIHNlcCA9ICI7IikgDQoNCiMgQ3JlYXRlIGEgZGF0YSBmcmFtZSB3aXRoIGNvdW50cyBvZiBhcnRpY2xlcyBmcm9tIGVhY2ggY291bnRyeQ0KZmlyc3Rjb3VudHJ5Y291bnRzIDwtIGJpYm1hcCAlPiUgDQogIGdyb3VwX2J5KEFVMV9DTykgJT4lIA0KICBjb3VudCgpICU+JSANCiAgZmlsdGVyKCFpcy5uYShBVTFfQ08pKSAgDQoNCiMgTG9hZCB3b3JsZCBtYXAgZGF0YSBhbmQgcmVtb3ZlIGNvdW50cmllcyB3aXRoIGxvbmdpdHVkZSA+MTgwIHRvIG1ha2UgYW4gZXF1YWwgcHJvamVjdGlvbi1saWtlIG1hcA0Kd29ybGRfbWFwIDwtIG1hcF9kYXRhKCJ3b3JsZCIpICU+JSANCiAgZmlsdGVyKCEgbG9uZyA+IDE4MCkNCg0KIyBGb3JtYXQgY291bnRyeSBuYW1lcyB0byBtYXRjaCByZWdpb25zIG9uIHRoZSB3b3JsZCBtYXANCmZpcnN0Y291bnRyeWNvdW50cyRyZWdpb24gPC0gc3RyX3RvX3RpdGxlKGZpcnN0Y291bnRyeWNvdW50cyRBVTFfQ08pDQpmaXJzdGNvdW50cnljb3VudHMkcmVnaW9uW2ZpcnN0Y291bnRyeWNvdW50cyRyZWdpb24gPT0gIlVzYSJdIDwtICJVU0EiIA0KZmlyc3Rjb3VudHJ5Y291bnRzJHJlZ2lvbltmaXJzdGNvdW50cnljb3VudHMkcmVnaW9uID09ICJLb3JlYSJdIDwtICJTb3V0aCBLb3JlYSINCg0KIyBKb2luIGNvdW50IGRhdGEgd2l0aCBtYXAgZGF0YSBhbmQgc2V0IG1pc3NpbmcgY291bnRzIHRvIHplcm8NCmVtcHR5bWFwIDwtIHRpYmJsZShyZWdpb24gPSB1bmlxdWUod29ybGRfbWFwJHJlZ2lvbiksIG4gPSByZXAoMCxsZW5ndGgodW5pcXVlKHdvcmxkX21hcCRyZWdpb24pKSkpDQpmdWxsbWFwIDwtIGxlZnRfam9pbihlbXB0eW1hcCwgZmlyc3Rjb3VudHJ5Y291bnRzLCBieSA9ICJyZWdpb24iKQ0KZnVsbG1hcCRuIDwtIGZ1bGxtYXAkbi54ICsgZnVsbG1hcCRuLnkNCmZ1bGxtYXAkbltpcy5uYShmdWxsbWFwJG4pXSA8LSAwDQoNCiMgQ3JlYXRlIGEgcGxvdCBvZiB0aGUgd29ybGQgbWFwIHdpdGggcmVnaW9ucyBjb2xvcmVkIGJhc2VkIG9uIGFydGljbGUgY291bnRzDQpmaWc3IDwtIGZ1bGxtYXAgJT4lDQogIGdncGxvdChhZXMoZmlsbCA9IG4sIG1hcF9pZCA9IHJlZ2lvbikpICsNCiAgZ2VvbV9tYXAobWFwID0gd29ybGRfbWFwKSArDQogIGV4cGFuZF9saW1pdHMoeCA9IHdvcmxkX21hcCRsb25nLCB5ID0gd29ybGRfbWFwJGxhdCkgKw0KICBjb29yZF9tYXAoIm1vbGwiKSArICMgTW9sbHdlaWRlIHByb2plY3Rpb24NCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoDQogICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLCAgDQogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgIA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLA0KICAgIGxlZ2VuZC5ib3ggPSAiaG9yaXpvbnRhbCIsICANCiAgICBsZWdlbmQuYm94Lmp1c3QgPSAiY2VudGVyIiwgIA0KICAgIGxlZ2VuZC5tYXJnaW4gPSBtYXJnaW4odCA9IDEwLCB1bml0ID0gInB0IiksICANCiAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLCANCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBmYWNlID0gImJvbGQiKSwgIA0KICAgIGxlZ2VuZC5rZXkud2lkdGggPSB1bml0KDMwLCAibW0iKSAgDQogICkgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KA0KICAgIGxvdyA9ICIjRUNGMjA3IiwgaGlnaCA9ICIjQzMwN0YyIiwNCiAgICBuYW1lID0gIlNjb3JlIiwgbmEudmFsdWUgPSAiZ3JheTcwIiwNCiAgICBsaW1pdHMgPSBjKDEsIDIwKQ0KICAgICkgKw0KICBndWlkZXMoDQogICAgZmlsbCA9IGd1aWRlX2NvbG91cmJhcigNCiAgICAgIGJhcndpZHRoID0gdW5pdCgxODAsIHVuaXRzID0gIm1tIiksDQogICAgICBiYXJoZWlnaHQgPSB1bml0KDMsIHVuaXRzID0gIm1tIikNCiAgICApDQogICkNCg0KIA0KZmlnNw0KIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzdfd29ybGRfbWFwLnBkZiIpLCB3aWR0aCA9IDIwLCBoZWlnaHQgPSAxMSwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9ODAwKQ0KIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzdfd29ybGRfbWFwLmpwZyIpLCB3aWR0aCA9IDIwLCBoZWlnaHQgPSAxMSwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9ODAwKQ0KDQogDQpgYGANCg0KIyMgRmlndXJlIHMyOSANCkNvdW50cnktbGV2ZWwgY29sbGFib3JhdGlvbiBuZXR3b3JrIGNpcmNsZSBwbG90IHdpdGggc2VsZi1jb2xsYWJvcmF0aW9ucyBpbmNsdWRlZCwgYmFzZWQgb24gYWZmaWxpYXRpb24gY291bnRyaWVzIG9mIHRoZSBhdXRob3JzIG9mIHBhcGVycyBpbmNsdWRlZCBpbiB0aGUgc3lzdGVtYXRpYyBtYXANCmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01fQ0KIyBFeHRyYWN0IGNvdW50cmllcyBmcm9tIHRoZSBhZmZpbGlhdGlvbnMNCmJpYl9zY28yIDwtIG1ldGFUYWdFeHRyYWN0aW9uKGJpYl9zY28sIEZpZWxkID0gIkFVX0NPIiwgc2VwID0gIjsiKQ0KDQojIENyZWF0ZSBhIG5ldHdvcmsgbWF0cml4IG9mIGNvbGxhYm9yYXRpb25zIGJldHdlZW4gY291bnRyaWVzDQpOZXRNYXRyaXhfY291bnRyeSA8LSBiaWJsaW9OZXR3b3JrKGJpYl9zY28yLCBhbmFseXNpcyA9ICJjb2xsYWJvcmF0aW9uIiwgbmV0d29yayA9ICJjb3VudHJpZXMiLCBzZXAgPSAiOyIpDQoNCiMgQ29udmVydCB0aGUgbmV0d29yayBtYXRyaXggdG8gYSBzdGFuZGFyZCBtYXRyaXgNCk5ldE1hdHJpeF9jb3VudHJ5IDwtIGFzLm1hdHJpeChOZXRNYXRyaXhfY291bnRyeSkNCg0KIyBSZW1vdmUgdGhlIGxvd2VyIHRyaWFuZ2xlIChhcyB0aGlzIGlzIGR1cGxpY2F0aW9uIG9mIGluZm8pDQpOZXRNYXRyaXhfY291bnRyeVtsb3dlci50cmkoTmV0TWF0cml4X2NvdW50cnkpXSA8LSAwIA0KDQojIENoYW5nZSBjb2x1bW4gYW5kIHJvdyBuYW1lcyB0byB0aXRsZSBjYXNlDQpjb2xuYW1lcyhOZXRNYXRyaXhfY291bnRyeSkgPC0gc3RyX3RvX3RpdGxlKGNvbG5hbWVzKE5ldE1hdHJpeF9jb3VudHJ5KSkNCnJvd25hbWVzKE5ldE1hdHJpeF9jb3VudHJ5KSA8LSBzdHJfdG9fdGl0bGUocm93bmFtZXMoTmV0TWF0cml4X2NvdW50cnkpKQ0KDQojIENoYW5nZSAiVXNhIiB0byAiVVNBIg0KY29sbmFtZXMoTmV0TWF0cml4X2NvdW50cnkpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb3VudHJ5KSA9PSAiVXNhIl0gPC0gIlVTQSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb3VudHJ5KVtyb3duYW1lcyhOZXRNYXRyaXhfY291bnRyeSkgPT0gIlVzYSJdIDwtICJVU0EiDQoNCiMgQ2hhbmdlICJVbml0ZWQgS2luZ2RvbSIgdG8gIlVLIiANCmNvbG5hbWVzKE5ldE1hdHJpeF9jb3VudHJ5KVtjb2xuYW1lcyhOZXRNYXRyaXhfY291bnRyeSkgPT0gIlVuaXRlZCBLaW5nZG9tIl0gPC0gIlVLIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvdW50cnkpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb3VudHJ5KSA9PSAiVW5pdGVkIEtpbmdkb20iXSA8LSAiVUsiDQoNCm15LmNvbHMyIDwtIGMoDQogIFVTQSA9ICIjZTQxYTFjIiwNCiAgQ2FuYWRhID0gIiMzNzdlYjgiLA0KICBNZXhpY28gPSAiIzRkYWY0YSIsDQogIEJyYXppbCA9ICIjOTg0ZWEzIiwNCiAgRWN1YWRvciA9ICIjZmY3ZjAwIiwNCiAgQ2hpbGUgPSAiI2ZmZmYzMyIsDQogIFBoaWxpcHBpbmVzID0gIiNhNjU2MjgiLA0KICBDaGluYSA9ICIjZjc4MWJmIiwNCiAgS29yZWEgPSAiI2U0MWExYyIsDQogIEluZGlhID0gIiM5ODRlYTMiLA0KICBUdXJrZXkgPSAiI2ZmN2YwMCIsDQogIFJvbWFuaWEgPSAiIzRkYWY0YSIsDQogIFN3aXR6ZXJsYW5kID0gIiMzNzdlYjgiLA0KICBOb3J3YXkgPSAiIzFiOWU3NyIsDQogIE5ldGhlcmxhbmRzID0gIiNkOTVmMDIiLA0KICBHZXJtYW55ID0gIiM3NTcwYjMiLA0KICBGcmFuY2UgPSAiI2U3Mjk4YSIsDQogIEl0YWx5ID0gIiM2NmE2MWUiLA0KICBQb3J0dWdhbCA9ICIjZTZhYjAyIiwNCiAgU3BhaW4gPSAiI2E2NzYxZCIsDQogIFN3ZWRlbiA9ICIjNjY2NjY2Ig0KKQ0KDQogDQoNCiMgQ3JlYXRlIGEgY2hvcmQgZGlhZ3JhbSBvZiB0aGUgbmV0d29yayBtYXRyaXgNCmZpZ3MyOSA8LSBjaG9yZERpYWdyYW0oTmV0TWF0cml4X2NvdW50cnksIGFubm90YXRpb25UcmFjayA9ICJncmlkIiwgcHJlQWxsb2NhdGVUcmFja3MgPSAxLCBncmlkLmNvbCA9IG15LmNvbHMyKQ0KDQojIEFkZCBhIHRyYWNrIHRvIGxhYmVsIGVhY2ggc2VjdG9yIHdpdGggaXRzIG5hbWUNCmNpcmNvcy50cmFja1Bsb3RSZWdpb24odHJhY2suaW5kZXggPSAxLCBwYW5lbC5mdW4gPSBmdW5jdGlvbih4LCB5KSB7DQogIHhsaW0gPSBnZXQuY2VsbC5tZXRhLmRhdGEoInhsaW0iKQ0KICB5bGltID0gZ2V0LmNlbGwubWV0YS5kYXRhKCJ5bGltIikNCiAgc2VjdG9yLm5hbWUgPSBnZXQuY2VsbC5tZXRhLmRhdGEoInNlY3Rvci5pbmRleCIpDQogIGNpcmNvcy50ZXh0KG1lYW4oeGxpbSksIHlsaW1bMV0gKyAuMSwgc2VjdG9yLm5hbWUsIGZhY2luZyA9ICJjbG9ja3dpc2UiLCBuaWNlRmFjaW5nID0gVFJVRSwgYWRqID0gYygwLCAwLjUpKQ0KICBjaXJjb3MuYXhpcyhoID0gInRvcCIsIGxhYmVscy5jZXggPSAwLjUsIG1ham9yLnRpY2subGVuZ3RoID0gMC4yLCBzZWN0b3IuaW5kZXggPSBzZWN0b3IubmFtZSwgdHJhY2suaW5kZXggPSAyKQ0KfSwgYmcuYm9yZGVyID0gTkEpDQoNCg0KDQpgYGANCg0KIyMgRmlndXJlIHMzMCANCkNvdW50cnktbGV2ZWwgY29sbGFib3JhdGUgbmV0d29yayBjaXJjbGUgcGxvdCB3aXRoIHNlbGYtY29sbGFib3JhdGlvbnMgZXhjbHVkZWQsIGJhc2VkIG9uIGFmZmlsaWF0aW9uIGNvdW50cmllcyBvZiB0aGUgYXV0aG9ycyBvZiBwYXBlcnMgaW5jbHVkZWQgaW4gdGhlIHN5c3RlbWF0aWMgbWFwDQpgYGB7ciwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NX0NCiMgTWFraW5nIGRpYWduYWwgemVybyB0byByZW1vdmUgc2VsZiBjaXRhdGlvbnMgDQpkaWFnKE5ldE1hdHJpeF9jb3VudHJ5KSA8LSAwDQoNCiMgQ3JlYXRlIGEgY2hvcmQgZGlhZ3JhbSBvZiB0aGUgbmV0d29yayBtYXRyaXggICAgICAgICANCmZpZ3MzMCA8LSBjaG9yZERpYWdyYW0oTmV0TWF0cml4X2NvdW50cnksIGFubm90YXRpb25UcmFjayA9ICJncmlkIiwgcHJlQWxsb2NhdGVUcmFja3MgPSAxLCBncmlkLmNvbCA9IG15LmNvbHMyKQ0KDQojIEFkZCBhIHRyYWNrIHRvIGxhYmVsIGVhY2ggc2VjdG9yIHdpdGggaXRzIG5hbWUNCmNpcmNvcy50cmFja1Bsb3RSZWdpb24odHJhY2suaW5kZXggPSAxLCBwYW5lbC5mdW4gPSBmdW5jdGlvbih4LCB5KSB7DQogIHhsaW0gPSBnZXQuY2VsbC5tZXRhLmRhdGEoInhsaW0iKQ0KICB5bGltID0gZ2V0LmNlbGwubWV0YS5kYXRhKCJ5bGltIikNCiAgc2VjdG9yLm5hbWUgPSBnZXQuY2VsbC5tZXRhLmRhdGEoInNlY3Rvci5pbmRleCIpDQogIGNpcmNvcy50ZXh0KG1lYW4oeGxpbSksIHlsaW1bMV0gKyAuMSwgc2VjdG9yLm5hbWUsIGZhY2luZyA9ICJjbG9ja3dpc2UiLCBuaWNlRmFjaW5nID0gVFJVRSwgYWRqID0gYygwLCAwLjUpKQ0KICBjaXJjb3MuYXhpcyhoID0gInRvcCIsIGxhYmVscy5jZXggPSAwLjUsIG1ham9yLnRpY2subGVuZ3RoID0gMC4yLCBzZWN0b3IuaW5kZXggPSBzZWN0b3IubmFtZSwgdHJhY2suaW5kZXggPSAyKQ0KfSwgYmcuYm9yZGVyID0gTkEpDQpgYGANCg0KIyMgRmlndXJlIHMzMQ0KQ29udGluZW50LWxldmVsIGNvbGxhYm9yYXRlIG5ldHdvcmsgY2lyY2xlIHBsb3Qgd2l0aCBzZWxmLWNvbGxhYm9yYXRpb25zIGluY2x1ZGVkLCBiYXNlZCBvbiBhZmZpbGlhdGlvbiBjb3VudHJpZXMgb2YgdGhlIGF1dGhvcnMgb2YgcGFwZXJzIGluY2x1ZGVkIGluIHRoZSBzeXN0ZW1hdGljIG1hcCANCmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01fQ0KTmV0TWF0cml4X2NvbnRpbmVudCA8LSBOZXRNYXRyaXhfY291bnRyeQ0KIyBDaGFuZ2UgIlVzYSIgdG8gIk5vcnRoIEFtZXJpY2EiDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiVVNBIl0gPC0gIk5vcnRoICBcbkFtZXJpY2EiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiVVNBIl0gPC0gIk5vcnRoICBcbkFtZXJpY2EiDQojIENoYW5nZSAiVXNhIiB0byAiTm9ydGggQW1lcmljYSINCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJDYW5hZGEiXSA8LSAiTm9ydGggIFxuQW1lcmljYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJDYW5hZGEiXSA8LSAiTm9ydGggIFxuQW1lcmljYSINCiMgQ2hhbmdlICJNZXhpY28iIHRvICJOb3J0aCBBbWVyaWNhIg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIk1leGljbyJdIDwtICJOb3J0aCAgXG5BbWVyaWNhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIk1leGljbyJdIDwtICJOb3J0aCAgXG5BbWVyaWNhIg0KIyBDaGFuZ2UgQ2hpbmEgdG8gQXNpYQ0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkNoaW5hIl0gPC0gIkFzaWEiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQ2hpbmEiXSA8LSAiQXNpYSINCiMgQ2hhbmdlIEluZGlhIHRvIEFzaWENCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJJbmRpYSJdIDwtICJBc2lhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkluZGlhIl0gPC0gIkFzaWEiDQojIENoYW5nZSBQaGlsbGlwaW5lcyB0byBBc2lhDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiUGhpbGlwcGluZXMiXSA8LSAiQXNpYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJQaGlsaXBwaW5lcyJdIDwtICJBc2lhIg0KIyBDaGFuZ2UgIkJyYXppbCIgdG8gIlNvdXRoIEFtZXJpY2EiDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQnJhemlsIl0gPC0gIlNvdXRoICBcbkFtZXJpY2EiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQnJhemlsIl0gPC0gIlNvdXRoICBcbkFtZXJpY2EiDQojIENoYW5nZSAiRWN1YWRvciIgdG8gIlNvdXRoIEFtZXJpY2EiDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiRWN1YWRvciJdIDwtICJTb3V0aCAgXG5BbWVyaWNhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkVjdWFkb3IiXSA8LSAiU291dGggIFxuQW1lcmljYSINCiMgQ2hhbmdlICJDaGlsZSIgdG8gIlNvdXRoIEFtZXJpY2EiDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQ2hpbGUiXSA8LSAiU291dGggIFxuQW1lcmljYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJDaGlsZSJdIDwtICJTb3V0aCAgXG5BbWVyaWNhIg0KIyBDaGFuZ2UgIlVuaXRlZCBLaW5nZG9tIiB0byAiRXVyb3BlIiANCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09IlVLIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09IlVLIl0gPC0gIkV1cm9wZSINCiMgQ2hhbmdlICJSb21hbmlhIiB0byAiRXVyb3BlIg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlJvbWFuaWEiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlJvbWFuaWEiXSA8LSAiRXVyb3BlIg0KIyBDaGFuZ2UgIkdlcm1hbnkiIHRvICJFdXJvcGUiDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiR2VybWFueSJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiR2VybWFueSJdIDwtICJFdXJvcGUiDQojQ2hhbmdlICJGcmFuY2UiIHRvICJFdXJvcGUiDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiRnJhbmNlIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJGcmFuY2UiXSA8LSAiRXVyb3BlIg0KI0NoYW5nZSAiU3BhaW4iIHRvICJFdXJvcGUiDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiU3BhaW4iXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlNwYWluIl0gPC0gIkV1cm9wZSINCiNDaGFuZ2UgIlBvcnR1Z2FsIiB0byAiRXVyb3BlIg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlBvcnR1Z2FsIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJQb3J0dWdhbCJdIDwtICJFdXJvcGUiDQojQ2hhbmdlICJTd2VkZW4iIHRvICJFdXJvcGUiDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiU3dlZGVuIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJTd2VkZW4iXSA8LSAiRXVyb3BlIg0KI0NoYW5nZSAiSXRhbHkiIHRvICJFdXJvcGUiDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiSXRhbHkiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkl0YWx5Il0gPC0gIkV1cm9wZSINCiNDaGFuZ2UgIk5ldGhlcmxhbmRzIiB0byAiRXVyb3BlIg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIk5ldGhlcmxhbmRzIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJOZXRoZXJsYW5kcyJdIDwtICJFdXJvcGUiDQojQ2hhbmdlICJOb3J3YXkiIHRvICJFdXJvcGUiDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiTm9yd2F5Il0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJOb3J3YXkiXSA8LSAiRXVyb3BlIg0KI0NoYW5nZSAiU3dpdHplcmxhbmQiIHRvICJFdXJvcGUiDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiU3dpdHplcmxhbmQiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlN3aXR6ZXJsYW5kIl0gPC0gIkV1cm9wZSINCiNDaGFuZ2UgIkN6ZWNoIFJlcHVibGljIiB0byAiRXVyb3BlIg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkN6ZWNoIFJlcHVibGljIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJDemVjaCBSZXB1YmxpYyJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJLb3JlYSJdIDwtICJBc2lhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIktvcmVhIl0gPC0gIkFzaWEiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJUdXJrZXkiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlR1cmtleSJdIDwtICJFdXJvcGUiDQoNCg0KIyBjb2xsYXBzaW5nDQptZXJnZV9tYXRyaXggPC0gdChyb3dzdW0odChOZXRNYXRyaXhfY29udGluZW50KSwgZ3JvdXAgPSBjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSwgbmEucm0gPSBUKSkNCm1lcmdlX21hdHJpeDIgPC0gcm93c3VtKG1lcmdlX21hdHJpeCwgZ3JvdXAgPSByb3duYW1lcyhtZXJnZV9tYXRyaXgpKQ0KDQoNCiMgQ3JlYXRlIGEgY2hvcmQgZGlhZ3JhbSBvZiB0aGUgbmV0d29yayBtYXRyaXgNCmZpZ3MzMSA8LSBjaG9yZERpYWdyYW0obWVyZ2VfbWF0cml4MiwgYW5ub3RhdGlvblRyYWNrID0gImdyaWQiLCBwcmVBbGxvY2F0ZVRyYWNrcyA9IDEpDQojIEFkZCBhIHRyYWNrIHRvIGxhYmVsIGVhY2ggc2VjdG9yIHdpdGggaXRzIG5hbWUNCmNpcmNvcy50cmFja1Bsb3RSZWdpb24odHJhY2suaW5kZXggPSAxLCBwYW5lbC5mdW4gPSBmdW5jdGlvbih4LCB5KSB7DQogIHhsaW0gPSBnZXQuY2VsbC5tZXRhLmRhdGEoInhsaW0iKQ0KICB5bGltID0gZ2V0LmNlbGwubWV0YS5kYXRhKCJ5bGltIikNCiAgc2VjdG9yLm5hbWUgPSBnZXQuY2VsbC5tZXRhLmRhdGEoInNlY3Rvci5pbmRleCIpDQogIGNpcmNvcy50ZXh0KG1lYW4oeGxpbSksIHlsaW1bMV0gKyAwLjIsIHNlY3Rvci5uYW1lLCBmYWNpbmcgPSAiY2xvY2t3aXNlIiwgbmljZUZhY2luZyA9IFRSVUUsIGFkaiA9IGMoMCwgMSkpDQogIGNpcmNvcy5heGlzKGggPSAidG9wIiwgbGFiZWxzLmNleCA9IDAuNSwgbWFqb3IudGljay5sZW5ndGggPSAwLjIsIHNlY3Rvci5pbmRleCA9IHNlY3Rvci5uYW1lLCB0cmFjay5pbmRleCA9IDIpDQp9LCBiZy5ib3JkZXIgPSBOQSkNCg0KDQpgYGANCg0KIyMgRmlndXJlIDggDQpBIGNob3JkIGRpYWdyYW0gaWxsdXN0cmF0aW9uIG9mIGNvbGxhYm9yYXRpb25zIGFjcm9zcyBjb250aW5lbnRzLiBDb250aW5lbnRzIHJlcHJlc2VudCB0aGUgbG9jYXRpb24gb2YgdGhlIHByaW1hcnkgYXV0aG9yc+KAmSBhZmZpbGlhdGVkIGluc3RpdHV0aW9uLiBDb2xsYWJvcmF0aW9ucyB3aXRoaW4gY29udGluZW50cyBhcmUgbm90IHNob3duLg0KYGBge3J9DQojIHJlbW92ZSBkaWFnb25hbCBlbGVtZW50cw0KZGlhZyhtZXJnZV9tYXRyaXgyKSA8LSAwDQoNCiMgQ3JlYXRlIGEgY2hvcmQgZGlhZ3JhbSBvZiB0aGUgbmV0d29yayBtYXRyaXgNCmZpZzggPC0gY2hvcmREaWFncmFtKG1lcmdlX21hdHJpeDIsIGFubm90YXRpb25UcmFjayA9ICJncmlkIiwgcHJlQWxsb2NhdGVUcmFja3MgPSAxKQ0KDQojIEFkZCBhIHRyYWNrIHRvIGxhYmVsIGVhY2ggc2VjdG9yIHdpdGggaXRzIG5hbWUNCmNpcmNvcy50cmFja1Bsb3RSZWdpb24odHJhY2suaW5kZXggPSAxLCBwYW5lbC5mdW4gPSBmdW5jdGlvbih4LCB5KSB7DQogIHhsaW0gPSBnZXQuY2VsbC5tZXRhLmRhdGEoInhsaW0iKQ0KICB5bGltID0gZ2V0LmNlbGwubWV0YS5kYXRhKCJ5bGltIikNCiAgc2VjdG9yLm5hbWUgPSBnZXQuY2VsbC5tZXRhLmRhdGEoInNlY3Rvci5pbmRleCIpDQogIGNpcmNvcy50ZXh0KG1lYW4oeGxpbSksIHlsaW1bMV0gKyAwLjIsIHNlY3Rvci5uYW1lLCBmYWNpbmcgPSAiY2xvY2t3aXNlIiwgbmljZUZhY2luZyA9IFRSVUUsIGFkaiA9IGMoMCwgMSkpDQogIGNpcmNvcy5heGlzKGggPSAidG9wIiwgbGFiZWxzLmNleCA9IDAuNSwgbWFqb3IudGljay5sZW5ndGggPSAwLjIsIHNlY3Rvci5pbmRleCA9IHNlY3Rvci5uYW1lLCB0cmFjay5pbmRleCA9IDIpDQp9LCBiZy5ib3JkZXIgPSBOQSkNCg0KYGBgDQoNCg==